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 +4 -4
- data/CHANGELOG.md +35 -3
- data/config/default.yml +2 -5
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cop/rspec/around_block.rb +2 -4
- data/lib/rubocop/cop/rspec/change_by_zero.rb +4 -3
- data/lib/rubocop/cop/rspec/contain_exactly.rb +1 -0
- data/lib/rubocop/cop/rspec/context_wording.rb +15 -9
- data/lib/rubocop/cop/rspec/empty_example_group.rb +2 -0
- data/lib/rubocop/cop/rspec/empty_metadata.rb +1 -0
- data/lib/rubocop/cop/rspec/expect_actual.rb +1 -1
- data/lib/rubocop/cop/rspec/focus.rb +0 -6
- data/lib/rubocop/cop/rspec/indexed_let.rb +4 -3
- data/lib/rubocop/cop/rspec/match_array.rb +1 -0
- data/lib/rubocop/cop/rspec/metadata_style.rb +1 -6
- data/lib/rubocop/cop/rspec/mixin/metadata.rb +5 -8
- data/lib/rubocop/cop/rspec/mixin/top_level_group.rb +7 -0
- data/lib/rubocop/cop/rspec/pending_without_reason.rb +0 -5
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +3 -4
- data/lib/rubocop/cop/rspec/sort_metadata.rb +22 -8
- data/lib/rubocop/cop/rspec/stubbed_mock.rb +12 -9
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +3 -1
- data/lib/rubocop/cop/rspec/verified_double_reference.rb +14 -53
- data/lib/rubocop/cop/rspec/void_expect.rb +6 -1
- data/lib/rubocop/rspec/description_extractor.rb +2 -2
- data/lib/rubocop/rspec/hook.rb +1 -1
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +3 -6
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,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 `
|
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 `
|
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
|
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: '
|
992
|
+
VersionChanged: '3.4'
|
996
993
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubleReference
|
997
994
|
|
998
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
|
@@ -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
|
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
|
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
|
-
|
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)
|
@@ -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
|
-
|
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
|
-
|
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) }
|
@@ -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
|
72
|
+
add_offense(actual) do |corrector|
|
73
73
|
next unless CORRECTABLE_MATCHERS.include?(matcher)
|
74
74
|
next if literal?(expected)
|
75
75
|
|
@@ -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.
|
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
|
-
|
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
|
|
@@ -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
|
-
|
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
|
@@ -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
|
-
|
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
|
-
|
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
|
@@ -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
|
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(
|
159
|
-
|
160
|
-
|
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
|
-
|
167
|
+
'`allow`'
|
167
168
|
when :is_expected
|
168
|
-
'allow(subject)'
|
169
|
+
'`allow(subject)`'
|
169
170
|
when :expect_any_instance_of
|
170
|
-
|
171
|
+
'`allow_any_instance_of`'
|
172
|
+
else
|
173
|
+
'an allow statement'
|
171
174
|
end
|
172
175
|
end
|
173
176
|
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
|
@@ -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
|
-
|
66
|
-
|
65
|
+
[RSPEC_COP_CLASS_NAME,
|
66
|
+
RUBOCOP_COP_CLASS_NAME].include?(yardoc.superclass.path)
|
67
67
|
end
|
68
68
|
|
69
69
|
def abstract?
|
data/lib/rubocop/rspec/hook.rb
CHANGED
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
|
+
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
|
@@ -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.
|
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: []
|