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 +4 -4
- data/CHANGELOG.md +9 -2
- data/config/default.yml +1 -12
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cop/rspec/contain_exactly.rb +1 -0
- data/lib/rubocop/cop/rspec/empty_example_group.rb +2 -0
- data/lib/rubocop/cop/rspec/focus.rb +0 -6
- data/lib/rubocop/cop/rspec/match_array.rb +1 -0
- data/lib/rubocop/cop/rspec/mixin/metadata.rb +5 -8
- data/lib/rubocop/cop/rspec/pending_without_reason.rb +0 -5
- data/lib/rubocop/cop/rspec/sort_metadata.rb +22 -8
- data/lib/rubocop/cop/rspec/verified_double_reference.rb +14 -53
- data/lib/rubocop/cop/rspec_cops.rb +0 -1
- data/lib/rubocop/rspec/description_extractor.rb +2 -2
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +3 -7
- data/lib/rubocop/cop/rspec/string_as_instance_double_constant.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a2433cc3212de48725bca4fa2f8216ef0742950d1b0ad0a52e0d717050ede4e
|
4
|
+
data.tar.gz: 3e43165a772275ece7344813b6dfc5196669763013c0bedc3b75107cf6fa0f30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 `
|
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 `
|
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: '
|
992
|
+
VersionChanged: '3.4'
|
1004
993
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubleReference
|
1005
994
|
|
1006
995
|
RSpec/VerifiedDoubles:
|
data/config/obsoletion.yml
CHANGED
@@ -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
|
@@ -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) }
|
@@ -47,15 +47,12 @@ module RuboCop
|
|
47
47
|
private
|
48
48
|
|
49
49
|
def on_metadata_arguments(metadata_arguments)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
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
|
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
|
-
#
|
13
|
-
#
|
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
|
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
|
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
|
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
|
-
$
|
54
|
+
$str
|
71
55
|
...)
|
72
56
|
PATTERN
|
73
57
|
|
74
58
|
def on_send(node)
|
75
|
-
verified_double(node) do |
|
76
|
-
|
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
|
-
|
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
|
-
|
66
|
-
|
65
|
+
[RSPEC_COP_CLASS_NAME,
|
66
|
+
RUBOCOP_COP_CLASS_NAME].include?(yardoc.superclass.path)
|
67
67
|
end
|
68
68
|
|
69
69
|
def abstract?
|
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.
|
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:
|
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.
|
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
|