rubocop-rspec 2.16.0 → 2.17.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Join the chat at https://gitter.im/rubocop-rspec/Lobby](https://badges.gitter.im/rubocop-rspec/Lobby.svg)](https://gitter.im/rubocop-rspec/Lobby)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/rubocop-rspec.svg)](https://rubygems.org/gems/rubocop-rspec)
|
5
|
-
![CI](https://github.com/rubocop
|
5
|
+
![CI](https://github.com/rubocop/rubocop-rspec/workflows/CI/badge.svg)
|
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
|