rubocop-rspec 2.16.0 → 2.17.1
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 +17 -0
- data/README.md +1 -1
- data/config/default.yml +12 -0
- data/lib/rubocop/cop/rspec/capybara/match_style.rb +60 -0
- data/lib/rubocop/cop/rspec/context_method.rb +5 -1
- data/lib/rubocop/cop/rspec/context_wording.rb +0 -1
- data/lib/rubocop/cop/rspec/mixin/skip_or_pending.rb +1 -1
- data/lib/rubocop/cop/rspec/pending_without_reason.rb +10 -12
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +37 -2
- data/lib/rubocop/cop/rspec/rails/minitest_assertions.rb +60 -0
- data/lib/rubocop/cop/rspec/stubbed_mock.rb +1 -1
- data/lib/rubocop/cop/rspec/subject_stub.rb +0 -1
- data/lib/rubocop/cop/rspec_cops.rb +2 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5f767597141ddcf9b2e28f8f02490b63d2e0e4e2a5804a81383af2c4ae15332
|
4
|
+
data.tar.gz: 8f55d65178e33b86fb6b685499876e116dfe2665c1e8da201b462721982dc49c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a42691283f03313b47cd59c36d040f1bd10b7da16bed5f1b96d80bdf65fdc592ad1df94c2288c9e157f8c6a101e028500b3126a40657eb87c2c1345675d1957
|
7
|
+
data.tar.gz: f3803001a19e2871f96f18ce9053bb43551298affb4478d20bd3c30edcff7aa814690b5e1f6b978da77d53d17910372202360f307cc52962ce5dd4c600f34dca
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,23 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 2.17.1 (2023-01-16)
|
6
|
+
|
7
|
+
- Fix a false negative for `RSpec/Pending` when using skipped in metadata is multiline string. ([@ydah])
|
8
|
+
- Fix a false positive for `RSpec/NoExpectationExample` when using skipped in metadata is multiline string. ([@ydah])
|
9
|
+
- Fix a false positive for `RSpec/ContextMethod` when multi-line context with `#` at the beginning. ([@ydah])
|
10
|
+
- Fix an incorrect autocorrect for `RSpec/PredicateMatcher` when multiline expect and predicate method with heredoc. ([@ydah])
|
11
|
+
- Fix a false positive for `RSpec/PredicateMatcher` when `include` with multiple argument. ([@ydah])
|
12
|
+
|
13
|
+
## 2.17.0 (2023-01-13)
|
14
|
+
|
15
|
+
- Fix a false positive for `RSpec/PendingWithoutReason` when pending/skip is argument of methods. ([@ydah])
|
16
|
+
- Add new `RSpec/Capybara/MatchStyle` cop. ([@ydah])
|
17
|
+
- Add new `RSpec/Rails/MinitestAssertions` cop. ([@ydah])
|
18
|
+
- Fix a false positive for `RSpec/PendingWithoutReason` when not inside example. ([@ydah])
|
19
|
+
- Fix a false negative for `RSpec/PredicateMatcher` when using `include` and `respond_to`. ([@ydah])
|
20
|
+
- Fix a false positive for `RSpec/StubbedMock` when stubbed message expectation with a block and block parameter. ([@ydah])
|
21
|
+
|
5
22
|
## 2.16.0 (2022-12-13)
|
6
23
|
|
7
24
|
- Add new `RSpec/FactoryBot/FactoryNameStyle` cop. ([@ydah])
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://gitter.im/rubocop-rspec/Lobby)
|
4
4
|
[](https://rubygems.org/gems/rubocop-rspec)
|
5
|
-

|
6
6
|
|
7
7
|
RSpec-specific analysis for your projects, as an extension to
|
8
8
|
[RuboCop](https://github.com/rubocop/rubocop).
|
data/config/default.yml
CHANGED
@@ -887,6 +887,12 @@ RSpec/Capybara/FeatureMethods:
|
|
887
887
|
VersionChanged: '2.0'
|
888
888
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods
|
889
889
|
|
890
|
+
RSpec/Capybara/MatchStyle:
|
891
|
+
Description: Checks for usage of deprecated style methods.
|
892
|
+
Enabled: pending
|
893
|
+
VersionAdded: '2.17'
|
894
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/MatchStyle
|
895
|
+
|
890
896
|
RSpec/Capybara/NegationMatcher:
|
891
897
|
Description: Enforces use of `have_no_*` or `not_to` for negated expectations.
|
892
898
|
Enabled: pending
|
@@ -1044,3 +1050,9 @@ RSpec/Rails/InferredSpecType:
|
|
1044
1050
|
routing: routing
|
1045
1051
|
system: system
|
1046
1052
|
views: view
|
1053
|
+
|
1054
|
+
RSpec/Rails/MinitestAssertions:
|
1055
|
+
Description: Check if using Minitest matchers.
|
1056
|
+
Enabled: pending
|
1057
|
+
VersionAdded: '2.17'
|
1058
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/MinitestAssertions
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
module Capybara
|
7
|
+
# Checks for usage of deprecated style methods.
|
8
|
+
#
|
9
|
+
# @example when using `assert_style`
|
10
|
+
# # bad
|
11
|
+
# page.find(:css, '#first').assert_style(display: 'block')
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# page.find(:css, '#first').assert_matches_style(display: 'block')
|
15
|
+
#
|
16
|
+
# @example when using `has_style?`
|
17
|
+
# # bad
|
18
|
+
# expect(page.find(:css, 'first')
|
19
|
+
# .has_style?(display: 'block')).to be true
|
20
|
+
#
|
21
|
+
# # good
|
22
|
+
# expect(page.find(:css, 'first')
|
23
|
+
# .matches_style?(display: 'block')).to be true
|
24
|
+
#
|
25
|
+
# @example when using `have_style`
|
26
|
+
# # bad
|
27
|
+
# expect(page).to have_style(display: 'block')
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# expect(page).to match_style(display: 'block')
|
31
|
+
#
|
32
|
+
class MatchStyle < Base
|
33
|
+
extend AutoCorrector
|
34
|
+
|
35
|
+
MSG = 'Use `%<good>s` instead of `%<bad>s`.'
|
36
|
+
RESTRICT_ON_SEND = %i[assert_style has_style? have_style].freeze
|
37
|
+
PREFERRED_METHOD = {
|
38
|
+
'assert_style' => 'assert_matches_style',
|
39
|
+
'has_style?' => 'matches_style?',
|
40
|
+
'have_style' => 'match_style'
|
41
|
+
}.freeze
|
42
|
+
|
43
|
+
def on_send(node)
|
44
|
+
method_node = node.loc.selector
|
45
|
+
add_offense(method_node) do |corrector|
|
46
|
+
corrector.replace(method_node,
|
47
|
+
PREFERRED_METHOD[method_node.source])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def message(node)
|
54
|
+
format(MSG, good: PREFERRED_METHOD[node.source], bad: node.source)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -31,7 +31,11 @@ module RuboCop
|
|
31
31
|
|
32
32
|
# @!method context_method(node)
|
33
33
|
def_node_matcher :context_method, <<-PATTERN
|
34
|
-
(block
|
34
|
+
(block
|
35
|
+
(send #rspec? :context
|
36
|
+
${(str #method_name?) (dstr (str #method_name?) ...)}
|
37
|
+
...)
|
38
|
+
...)
|
35
39
|
PATTERN
|
36
40
|
|
37
41
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
@@ -10,7 +10,6 @@ module RuboCop
|
|
10
10
|
# include `if`, `unless`, `for`, `before`, `after`, or `during`.
|
11
11
|
# They may consist of multiple words if desired.
|
12
12
|
#
|
13
|
-
# @see https://rspec.rubystyle.guide/#context-descriptions
|
14
13
|
# @see http://www.betterspecs.org/#contexts
|
15
14
|
#
|
16
15
|
# @example `Prefixes` configuration
|
@@ -11,7 +11,7 @@ module RuboCop
|
|
11
11
|
def_node_matcher :skipped_in_metadata?, <<-PATTERN
|
12
12
|
{
|
13
13
|
(send _ _ <#skip_or_pending? ...>)
|
14
|
-
(send _ _ ... (hash <(pair #skip_or_pending? { true str }) ...>))
|
14
|
+
(send _ _ ... (hash <(pair #skip_or_pending? { true str dstr }) ...>))
|
15
15
|
}
|
16
16
|
PATTERN
|
17
17
|
|
@@ -87,35 +87,33 @@ module RuboCop
|
|
87
87
|
(send #rspec? {#ExampleGroups.all #Examples.all} ... {<(sym :skip) ...> (hash <(pair (sym :skip) true) ...>)})
|
88
88
|
PATTERN
|
89
89
|
|
90
|
+
# @!method without_reason?(node)
|
91
|
+
def_node_matcher :without_reason?, <<~PATTERN
|
92
|
+
(send nil? ${:pending :skip})
|
93
|
+
PATTERN
|
94
|
+
|
90
95
|
def on_send(node)
|
91
96
|
if pending_without_reason?(node)
|
92
97
|
add_offense(node, message: 'Give the reason for pending.')
|
93
98
|
elsif skipped_without_reason?(node)
|
94
99
|
add_offense(node, message: 'Give the reason for skip.')
|
100
|
+
elsif without_reason?(node) && example?(node.parent)
|
101
|
+
add_offense(node,
|
102
|
+
message: "Give the reason for #{node.method_name}.")
|
95
103
|
end
|
96
104
|
end
|
97
105
|
|
98
106
|
private
|
99
107
|
|
100
|
-
def pending_by_pending_step_without_reason?(node)
|
101
|
-
node.method?(:pending) && node.first_argument.nil?
|
102
|
-
end
|
103
|
-
|
104
108
|
def pending_without_reason?(node)
|
105
109
|
pending_by_example_method?(node.block_node) ||
|
106
|
-
pending_by_metadata_without_reason?(node)
|
107
|
-
pending_by_pending_step_without_reason?(node)
|
108
|
-
end
|
109
|
-
|
110
|
-
def skipped_by_skip_step_without_reason?(node)
|
111
|
-
node.method?(:skip) && node.first_argument.nil?
|
110
|
+
pending_by_metadata_without_reason?(node)
|
112
111
|
end
|
113
112
|
|
114
113
|
def skipped_without_reason?(node)
|
115
114
|
skipped_by_example_group_method?(node.block_node) ||
|
116
115
|
skipped_by_example_method?(node.block_node) ||
|
117
|
-
skipped_by_metadata_without_reason?(node)
|
118
|
-
skipped_by_skip_step_without_reason?(node)
|
116
|
+
skipped_by_metadata_without_reason?(node)
|
119
117
|
end
|
120
118
|
end
|
121
119
|
end
|
@@ -118,7 +118,7 @@ module RuboCop
|
|
118
118
|
end
|
119
119
|
|
120
120
|
# A helper for `explicit` style
|
121
|
-
module ExplicitHelper
|
121
|
+
module ExplicitHelper # rubocop:disable Metrics/ModuleLength
|
122
122
|
include RuboCop::RSpec::Language
|
123
123
|
extend NodePattern::Macros
|
124
124
|
|
@@ -149,12 +149,35 @@ module RuboCop
|
|
149
149
|
return if part_of_ignored_node?(node)
|
150
150
|
|
151
151
|
predicate_matcher?(node) do |actual, matcher|
|
152
|
+
next unless replaceable_matcher?(matcher)
|
153
|
+
|
152
154
|
add_offense(node, message: message_explicit(matcher)) do |corrector|
|
155
|
+
next if uncorrectable_matcher?(node, matcher)
|
156
|
+
|
153
157
|
corrector_explicit(corrector, node, actual, matcher, matcher)
|
154
158
|
end
|
155
159
|
end
|
156
160
|
end
|
157
161
|
|
162
|
+
def replaceable_matcher?(matcher)
|
163
|
+
case matcher.method_name.to_s
|
164
|
+
when 'include'
|
165
|
+
matcher.arguments.one?
|
166
|
+
else
|
167
|
+
true
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def uncorrectable_matcher?(node, matcher)
|
172
|
+
heredoc_argument?(matcher) && !same_line?(node, matcher)
|
173
|
+
end
|
174
|
+
|
175
|
+
def heredoc_argument?(matcher)
|
176
|
+
matcher.arguments.select do |arg|
|
177
|
+
%i[str dstr xstr].include?(arg.type)
|
178
|
+
end.any?(&:heredoc?)
|
179
|
+
end
|
180
|
+
|
158
181
|
# @!method predicate_matcher?(node)
|
159
182
|
def_node_matcher :predicate_matcher?, <<-PATTERN
|
160
183
|
(send
|
@@ -179,7 +202,8 @@ module RuboCop
|
|
179
202
|
|
180
203
|
return false if allowed_explicit_matchers.include?(name)
|
181
204
|
|
182
|
-
name.start_with?('be_', 'have_') && !name.end_with?('?')
|
205
|
+
name.start_with?('be_', 'have_') && !name.end_with?('?') ||
|
206
|
+
%w[include respond_to].include?(name)
|
183
207
|
end
|
184
208
|
|
185
209
|
def message_explicit(matcher)
|
@@ -270,6 +294,17 @@ module RuboCop
|
|
270
294
|
# # good - the above code is rewritten to it by this cop
|
271
295
|
# expect(foo.something?).to be(true)
|
272
296
|
#
|
297
|
+
# # bad - no autocorrect
|
298
|
+
# expect(foo)
|
299
|
+
# .to be_something(<<~TEXT)
|
300
|
+
# bar
|
301
|
+
# TEXT
|
302
|
+
#
|
303
|
+
# # good
|
304
|
+
# expect(foo.something?(<<~TEXT)).to be(true)
|
305
|
+
# bar
|
306
|
+
# TEXT
|
307
|
+
#
|
273
308
|
# @example Strict: false, EnforcedStyle: explicit
|
274
309
|
# # bad
|
275
310
|
# expect(foo).to be_something
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
module Rails
|
7
|
+
# Check if using Minitest matchers.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# assert_equal(a, b)
|
12
|
+
# assert_equal a, b, "must be equal"
|
13
|
+
# refute_equal(a, b)
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# expect(a).to eq(b)
|
17
|
+
# expect(a).to(eq(b), "must be equal")
|
18
|
+
# expect(a).not_to eq(b)
|
19
|
+
#
|
20
|
+
class MinitestAssertions < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
23
|
+
MSG = 'Use `%<prefer>s`.'
|
24
|
+
RESTRICT_ON_SEND = %i[assert_equal refute_equal].freeze
|
25
|
+
|
26
|
+
# @!method minitest_assertion(node)
|
27
|
+
def_node_matcher :minitest_assertion, <<-PATTERN
|
28
|
+
(send nil? {:assert_equal :refute_equal} $_ $_ $_?)
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def on_send(node)
|
32
|
+
minitest_assertion(node) do |expected, actual, failure_message|
|
33
|
+
prefer = replacement(node, expected, actual,
|
34
|
+
failure_message.first)
|
35
|
+
add_offense(node, message: message(prefer)) do |corrector|
|
36
|
+
corrector.replace(node, prefer)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def replacement(node, expected, actual, failure_message)
|
44
|
+
runner = node.method?(:assert_equal) ? 'to' : 'not_to'
|
45
|
+
if failure_message.nil?
|
46
|
+
"expect(#{expected.source}).#{runner} eq(#{actual.source})"
|
47
|
+
else
|
48
|
+
"expect(#{expected.source}).#{runner}(eq(#{actual.source}), " \
|
49
|
+
"#{failure_message.source})"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def message(prefer)
|
54
|
+
format(MSG, prefer: prefer)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -91,7 +91,7 @@ module RuboCop
|
|
91
91
|
# @param node [RuboCop::AST::Node]
|
92
92
|
# @yield [RuboCop::AST::Node] matcher
|
93
93
|
def_node_matcher :matcher_with_return_block, <<~PATTERN
|
94
|
-
(block #message_expectation? args _) # receive(:foo) { 'bar' }
|
94
|
+
(block #message_expectation? (args) _) # receive(:foo) { 'bar' }
|
95
95
|
PATTERN
|
96
96
|
|
97
97
|
# @!method matcher_with_hash(node)
|
@@ -12,7 +12,6 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# @see https://robots.thoughtbot.com/don-t-stub-the-system-under-test
|
14
14
|
# @see https://penelope.zone/2015/12/27/introducing-rspec-smells-and-where-to-find-them.html#smell-1-stubjec
|
15
|
-
# @see https://github.com/rubocop-hq/rspec-style-guide#dont-stub-subject
|
16
15
|
#
|
17
16
|
# @example
|
18
17
|
# # bad
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative 'rspec/capybara/current_path_expectation'
|
4
4
|
require_relative 'rspec/capybara/feature_methods'
|
5
|
+
require_relative 'rspec/capybara/match_style'
|
5
6
|
require_relative 'rspec/capybara/negation_matcher'
|
6
7
|
require_relative 'rspec/capybara/specific_actions'
|
7
8
|
require_relative 'rspec/capybara/specific_finders'
|
@@ -23,6 +24,7 @@ rescue LoadError
|
|
23
24
|
# Rails/HttpStatus cannot be loaded if rack/utils is unavailable.
|
24
25
|
end
|
25
26
|
require_relative 'rspec/rails/inferred_spec_type'
|
27
|
+
require_relative 'rspec/rails/minitest_assertions'
|
26
28
|
|
27
29
|
require_relative 'rspec/align_left_let_brace'
|
28
30
|
require_relative 'rspec/align_right_let_brace'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-rspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.17.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Backus
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-01-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- lib/rubocop/cop/rspec/before_after_all.rb
|
59
59
|
- lib/rubocop/cop/rspec/capybara/current_path_expectation.rb
|
60
60
|
- lib/rubocop/cop/rspec/capybara/feature_methods.rb
|
61
|
+
- lib/rubocop/cop/rspec/capybara/match_style.rb
|
61
62
|
- lib/rubocop/cop/rspec/capybara/negation_matcher.rb
|
62
63
|
- lib/rubocop/cop/rspec/capybara/specific_actions.rb
|
63
64
|
- lib/rubocop/cop/rspec/capybara/specific_finders.rb
|
@@ -142,6 +143,7 @@ files:
|
|
142
143
|
- lib/rubocop/cop/rspec/rails/have_http_status.rb
|
143
144
|
- lib/rubocop/cop/rspec/rails/http_status.rb
|
144
145
|
- lib/rubocop/cop/rspec/rails/inferred_spec_type.rb
|
146
|
+
- lib/rubocop/cop/rspec/rails/minitest_assertions.rb
|
145
147
|
- lib/rubocop/cop/rspec/receive_counts.rb
|
146
148
|
- lib/rubocop/cop/rspec/receive_never.rb
|
147
149
|
- lib/rubocop/cop/rspec/repeated_description.rb
|
@@ -207,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
209
|
- !ruby/object:Gem::Version
|
208
210
|
version: '0'
|
209
211
|
requirements: []
|
210
|
-
rubygems_version: 3.
|
212
|
+
rubygems_version: 3.3.7
|
211
213
|
signing_key:
|
212
214
|
specification_version: 4
|
213
215
|
summary: Code style checking for RSpec files
|