rubocop-rspec 2.14.2 → 2.15.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 +13 -0
- data/config/default.yml +5 -12
- data/lib/rubocop/cop/rspec/factory_bot/consistent_parentheses_style.rb +11 -6
- data/lib/rubocop/cop/rspec/named_subject.rb +81 -6
- data/lib/rubocop/cop/rspec/nested_groups.rb +1 -1
- data/lib/rubocop/cop/rspec/repeated_description.rb +25 -2
- data/lib/rubocop/rspec/language.rb +4 -2
- data/lib/rubocop/rspec/shared_contexts/default_rspec_language_config_context.rb +29 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e120f8d06ef760cbe4f3a3d077ca6cd8ceeb274a26042a6e1469fe9a280c969
|
4
|
+
data.tar.gz: 0c80cc155e8f64b03a97de1327e454d9ff2efb1a75b02e3b098f868afed30d17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e982f97a23de2473c5cae6cd20bb653bcbcee806abddf0dda09c7b30692193858fc105c7b46ce3c004f28a7f680d1b3a475298c7b10d0e1499d5b80333fde504
|
7
|
+
data.tar.gz: c3b79b39a2c98d9103cb4edbf6c2d8e2cc957790fd8fa617e1fdece172f3dfaaf652bf482e7236a1da663f3b9afae943c17efee1e4a5f0293acc771bbc1c3c43
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 2.15.0 (2022-11-03)
|
6
|
+
|
7
|
+
- Fix a false positive for `RSpec/RepeatedDescription` when different its block expectations are used. ([@ydah])
|
8
|
+
- Add `named_only` style to `RSpec/NamedSubject`. ([@kuahyeow])
|
9
|
+
- Fix `RSpec/FactoryBot/ConsistentParenthesesStyle` to ignore calls without the first positional argument. ([@pirj])
|
10
|
+
- Fix `RSpec/FactoryBot/ConsistentParenthesesStyle` to ignore calls inside a Hash or an Array. ([@pirj])
|
11
|
+
- Fix `RSpec/NestedGroups` to correctly use `AllowedGroups` config. ([@samrjenkins])
|
12
|
+
- Remove `Runners` and `HookScopes` RSpec DSL elements from configuration. ([@pirj])
|
13
|
+
- Add `with default RSpec/Language config` helper to `lib` (under `rubocop/rspec/shared_contexts/default_rspec_language_config_context`), to allow use for downstream cops based on `RuboCop::Cop::RSpec::Base`. ([@smcgivern])
|
14
|
+
|
5
15
|
## 2.14.2 (2022-10-25)
|
6
16
|
|
7
17
|
- Fix an incorrect autocorrect for `FactoryBot/ConsistentParenthesesStyle` with `omit_parentheses` option when method name and first argument are not on same line. ([@ydah])
|
@@ -724,6 +734,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
724
734
|
[@jtannas]: https://github.com/jtannas
|
725
735
|
[@kellysutton]: https://github.com/kellysutton
|
726
736
|
[@koic]: https://github.com/koic
|
737
|
+
[@kuahyeow]: https://github.com/kuahyeow
|
727
738
|
[@lazycoder9]: https://github.com/lazycoder9
|
728
739
|
[@leoarnold]: https://github.com/leoarnold
|
729
740
|
[@liberatys]: https://github.com/Liberatys
|
@@ -760,9 +771,11 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
760
771
|
[@rrosenblum]: https://github.com/rrosenblum
|
761
772
|
[@rspeicher]: https://github.com/rspeicher
|
762
773
|
[@rst-j]: https://github.com/RST-J
|
774
|
+
[@samrjenkins]: https://github.com/samrjenkins
|
763
775
|
[@schmijos]: https://github.com/schmijos
|
764
776
|
[@seanpdoyle]: https://github.com/seanpdoyle
|
765
777
|
[@sl4vr]: https://github.com/sl4vr
|
778
|
+
[@smcgivern]: https://github.com/smcgivern
|
766
779
|
[@stephannv]: https://github.com/stephannv
|
767
780
|
[@t3h2mas]: https://github.com/t3h2mas
|
768
781
|
[@tdeo]: https://github.com/tdeo
|
data/config/default.yml
CHANGED
@@ -12,8 +12,6 @@ RSpec:
|
|
12
12
|
- Expectations
|
13
13
|
- Helpers
|
14
14
|
- Hooks
|
15
|
-
- HookScopes
|
16
|
-
- Runners
|
17
15
|
- Subjects
|
18
16
|
ExampleGroups:
|
19
17
|
inherit_mode:
|
@@ -81,12 +79,6 @@ RSpec:
|
|
81
79
|
- prepend_after
|
82
80
|
- after
|
83
81
|
- append_after
|
84
|
-
HookScopes:
|
85
|
-
- each
|
86
|
-
- example
|
87
|
-
- context
|
88
|
-
- all
|
89
|
-
- suite
|
90
82
|
Includes:
|
91
83
|
inherit_mode:
|
92
84
|
merge:
|
@@ -98,10 +90,6 @@ RSpec:
|
|
98
90
|
- include_examples
|
99
91
|
Context:
|
100
92
|
- include_context
|
101
|
-
Runners:
|
102
|
-
- to
|
103
|
-
- to_not
|
104
|
-
- not_to
|
105
93
|
SharedGroups:
|
106
94
|
inherit_mode:
|
107
95
|
merge:
|
@@ -624,8 +612,13 @@ RSpec/MultipleSubjects:
|
|
624
612
|
RSpec/NamedSubject:
|
625
613
|
Description: Checks for explicitly referenced test subjects.
|
626
614
|
Enabled: true
|
615
|
+
EnforcedStyle: always
|
616
|
+
SupportedStyles:
|
617
|
+
- always
|
618
|
+
- named_only
|
627
619
|
IgnoreSharedExamples: true
|
628
620
|
VersionAdded: 1.5.3
|
621
|
+
VersionChanged: '2.15'
|
629
622
|
StyleGuide: https://rspec.rubystyle.guide/#use-subject
|
630
623
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NamedSubject
|
631
624
|
|
@@ -55,15 +55,18 @@ module RuboCop
|
|
55
55
|
|
56
56
|
FACTORY_CALLS = RuboCop::RSpec::FactoryBot::Language::METHODS
|
57
57
|
|
58
|
+
RESTRICT_ON_SEND = FACTORY_CALLS
|
59
|
+
|
58
60
|
# @!method factory_call(node)
|
59
61
|
def_node_matcher :factory_call, <<-PATTERN
|
60
|
-
|
61
|
-
|
62
|
-
|
62
|
+
(send
|
63
|
+
{#factory_bot? nil?} %FACTORY_CALLS
|
64
|
+
{sym str send lvar} _*
|
65
|
+
)
|
63
66
|
PATTERN
|
64
67
|
|
65
68
|
def on_send(node)
|
66
|
-
return if
|
69
|
+
return if ambiguous_without_parentheses?(node)
|
67
70
|
|
68
71
|
factory_call(node) do
|
69
72
|
if node.parenthesized?
|
@@ -93,8 +96,10 @@ module RuboCop
|
|
93
96
|
end
|
94
97
|
end
|
95
98
|
|
96
|
-
def
|
97
|
-
node.parent&.send_type?
|
99
|
+
def ambiguous_without_parentheses?(node)
|
100
|
+
node.parent&.send_type? ||
|
101
|
+
node.parent&.pair_type? ||
|
102
|
+
node.parent&.array_type?
|
98
103
|
end
|
99
104
|
|
100
105
|
private
|
@@ -12,11 +12,11 @@ module RuboCop
|
|
12
12
|
# should be the most important object in your tests so they deserve
|
13
13
|
# a descriptive name.
|
14
14
|
#
|
15
|
-
# This cop can be configured in your configuration using
|
16
|
-
# `IgnoreSharedExamples` which will not report offenses for implicit
|
15
|
+
# This cop can be configured in your configuration using `EnforcedStyle`,
|
16
|
+
# and `IgnoreSharedExamples` which will not report offenses for implicit
|
17
17
|
# subjects in shared example groups.
|
18
18
|
#
|
19
|
-
# @example
|
19
|
+
# @example `EnforcedStyle: always` (default)
|
20
20
|
# # bad
|
21
21
|
# RSpec.describe User do
|
22
22
|
# subject { described_class.new }
|
@@ -27,7 +27,7 @@ module RuboCop
|
|
27
27
|
# end
|
28
28
|
#
|
29
29
|
# # good
|
30
|
-
# RSpec.describe
|
30
|
+
# RSpec.describe User do
|
31
31
|
# subject(:user) { described_class.new }
|
32
32
|
#
|
33
33
|
# it 'is valid' do
|
@@ -36,13 +36,49 @@ module RuboCop
|
|
36
36
|
# end
|
37
37
|
#
|
38
38
|
# # also good
|
39
|
-
# RSpec.describe
|
39
|
+
# RSpec.describe User do
|
40
|
+
# subject(:user) { described_class.new }
|
41
|
+
#
|
42
|
+
# it { is_expected.to be_valid }
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# @example `EnforcedStyle: named_only`
|
46
|
+
# # bad
|
47
|
+
# RSpec.describe User do
|
48
|
+
# subject(:user) { described_class.new }
|
49
|
+
#
|
50
|
+
# it 'is valid' do
|
51
|
+
# expect(subject.valid?).to be(true)
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# # good
|
56
|
+
# RSpec.describe User do
|
40
57
|
# subject(:user) { described_class.new }
|
41
58
|
#
|
59
|
+
# it 'is valid' do
|
60
|
+
# expect(user.valid?).to be(true)
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# # also good
|
65
|
+
# RSpec.describe User do
|
66
|
+
# subject { described_class.new }
|
67
|
+
#
|
42
68
|
# it { is_expected.to be_valid }
|
43
69
|
# end
|
44
70
|
#
|
71
|
+
# # acceptable
|
72
|
+
# RSpec.describe User do
|
73
|
+
# subject { described_class.new }
|
74
|
+
#
|
75
|
+
# it 'is valid' do
|
76
|
+
# expect(subject.valid?).to be(true)
|
77
|
+
# end
|
78
|
+
# end
|
45
79
|
class NamedSubject < Base
|
80
|
+
include ConfigurableEnforcedStyle
|
81
|
+
|
46
82
|
MSG = 'Name your test subject if you need to reference it explicitly.'
|
47
83
|
|
48
84
|
# @!method example_or_hook_block?(node)
|
@@ -62,14 +98,53 @@ module RuboCop
|
|
62
98
|
end
|
63
99
|
|
64
100
|
subject_usage(node) do |subject_node|
|
65
|
-
|
101
|
+
check_explicit_subject(subject_node)
|
66
102
|
end
|
67
103
|
end
|
68
104
|
|
105
|
+
private
|
106
|
+
|
69
107
|
def ignored_shared_example?(node)
|
70
108
|
cop_config['IgnoreSharedExamples'] &&
|
71
109
|
node.each_ancestor(:block).any?(&method(:shared_example?))
|
72
110
|
end
|
111
|
+
|
112
|
+
def check_explicit_subject(node)
|
113
|
+
return if allow_explicit_subject?(node)
|
114
|
+
|
115
|
+
add_offense(node.loc.selector)
|
116
|
+
end
|
117
|
+
|
118
|
+
def allow_explicit_subject?(node)
|
119
|
+
!always? && !named_only?(node)
|
120
|
+
end
|
121
|
+
|
122
|
+
def always?
|
123
|
+
style == :always
|
124
|
+
end
|
125
|
+
|
126
|
+
def named_only?(node)
|
127
|
+
style == :named_only &&
|
128
|
+
subject_definition_is_named?(node)
|
129
|
+
end
|
130
|
+
|
131
|
+
def subject_definition_is_named?(node)
|
132
|
+
subject = nearest_subject(node)
|
133
|
+
|
134
|
+
subject&.send_node&.arguments?
|
135
|
+
end
|
136
|
+
|
137
|
+
def nearest_subject(node)
|
138
|
+
node
|
139
|
+
.each_ancestor(:block)
|
140
|
+
.lazy
|
141
|
+
.map { |block_node| find_subject(block_node) }
|
142
|
+
.find(&:itself)
|
143
|
+
end
|
144
|
+
|
145
|
+
def find_subject(block_node)
|
146
|
+
block_node.body.child_nodes.find { |send_node| subject?(send_node) }
|
147
|
+
end
|
73
148
|
end
|
74
149
|
end
|
75
150
|
end
|
@@ -45,8 +45,12 @@ module RuboCop
|
|
45
45
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
46
46
|
return unless example_group?(node)
|
47
47
|
|
48
|
-
repeated_descriptions(node).each do |
|
49
|
-
add_offense(
|
48
|
+
repeated_descriptions(node).each do |description|
|
49
|
+
add_offense(description)
|
50
|
+
end
|
51
|
+
|
52
|
+
repeated_its(node).each do |its|
|
53
|
+
add_offense(its)
|
50
54
|
end
|
51
55
|
end
|
52
56
|
|
@@ -57,6 +61,7 @@ module RuboCop
|
|
57
61
|
grouped_examples =
|
58
62
|
RuboCop::RSpec::ExampleGroup.new(node)
|
59
63
|
.examples
|
64
|
+
.reject { |n| n.definition.method?(:its) }
|
60
65
|
.group_by { |example| example_signature(example) }
|
61
66
|
|
62
67
|
grouped_examples
|
@@ -66,9 +71,27 @@ module RuboCop
|
|
66
71
|
.map(&:definition)
|
67
72
|
end
|
68
73
|
|
74
|
+
def repeated_its(node)
|
75
|
+
grouped_its =
|
76
|
+
RuboCop::RSpec::ExampleGroup.new(node)
|
77
|
+
.examples
|
78
|
+
.select { |n| n.definition.method?(:its) }
|
79
|
+
.group_by { |example| its_signature(example) }
|
80
|
+
|
81
|
+
grouped_its
|
82
|
+
.select { |signatures, group| signatures.any? && group.size > 1 }
|
83
|
+
.values
|
84
|
+
.flatten
|
85
|
+
.map(&:to_node)
|
86
|
+
end
|
87
|
+
|
69
88
|
def example_signature(example)
|
70
89
|
[example.metadata, example.doc_string]
|
71
90
|
end
|
91
|
+
|
92
|
+
def its_signature(example)
|
93
|
+
[example.doc_string, example]
|
94
|
+
end
|
72
95
|
end
|
73
96
|
end
|
74
97
|
end
|
@@ -135,8 +135,9 @@ module RuboCop
|
|
135
135
|
end
|
136
136
|
|
137
137
|
module HookScopes # :nodoc:
|
138
|
+
ALL = %i[each example context all suite].freeze
|
138
139
|
def self.all(element)
|
139
|
-
|
140
|
+
ALL.include?(element)
|
140
141
|
end
|
141
142
|
end
|
142
143
|
|
@@ -158,8 +159,9 @@ module RuboCop
|
|
158
159
|
end
|
159
160
|
|
160
161
|
module Runners # :nodoc:
|
162
|
+
ALL = %i[to to_not not_to].freeze
|
161
163
|
def self.all(element)
|
162
|
-
|
164
|
+
ALL.include?(element)
|
163
165
|
end
|
164
166
|
end
|
165
167
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_context 'with default RSpec/Language config' do
|
4
|
+
include_context 'config'
|
5
|
+
|
6
|
+
# Deep duplication is needed to prevent config leakage between examples
|
7
|
+
let(:other_cops) do
|
8
|
+
default_language = RuboCop::ConfigLoader
|
9
|
+
.default_configuration['RSpec']['Language']
|
10
|
+
default_include = RuboCop::ConfigLoader
|
11
|
+
.default_configuration['RSpec']['Include']
|
12
|
+
{ 'RSpec' =>
|
13
|
+
{
|
14
|
+
'Include' => default_include,
|
15
|
+
'Language' => deep_dup(default_language)
|
16
|
+
} }
|
17
|
+
end
|
18
|
+
|
19
|
+
def deep_dup(object)
|
20
|
+
case object
|
21
|
+
when Array
|
22
|
+
object.map { |item| deep_dup(item) }
|
23
|
+
when Hash
|
24
|
+
object.transform_values(&method(:deep_dup))
|
25
|
+
else
|
26
|
+
object # only collections undergo modifications and need duping
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
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.15.0
|
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: 2022-
|
13
|
+
date: 2022-11-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -178,6 +178,7 @@ files:
|
|
178
178
|
- lib/rubocop/rspec/language.rb
|
179
179
|
- lib/rubocop/rspec/language/node_pattern.rb
|
180
180
|
- lib/rubocop/rspec/node.rb
|
181
|
+
- lib/rubocop/rspec/shared_contexts/default_rspec_language_config_context.rb
|
181
182
|
- lib/rubocop/rspec/version.rb
|
182
183
|
- lib/rubocop/rspec/wording.rb
|
183
184
|
homepage: https://github.com/rubocop/rubocop-rspec
|