rubocop-rspec 3.3.0 → 3.6.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 +26 -2
- data/README.md +7 -4
- data/config/default.yml +7 -12
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cop/rspec/be_eq.rb +1 -1
- data/lib/rubocop/cop/rspec/be_eql.rb +1 -1
- data/lib/rubocop/cop/rspec/be_nil.rb +4 -0
- data/lib/rubocop/cop/rspec/change_by_zero.rb +3 -4
- data/lib/rubocop/cop/rspec/contain_exactly.rb +1 -0
- data/lib/rubocop/cop/rspec/context_wording.rb +6 -1
- data/lib/rubocop/cop/rspec/described_class.rb +4 -2
- data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_example_group.rb +6 -4
- data/lib/rubocop/cop/rspec/example_wording.rb +1 -3
- data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_actual.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_change.rb +21 -2
- data/lib/rubocop/cop/rspec/focus.rb +15 -17
- data/lib/rubocop/cop/rspec/hook_argument.rb +2 -2
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +1 -1
- data/lib/rubocop/cop/rspec/implicit_expect.rb +3 -3
- data/lib/rubocop/cop/rspec/implicit_subject.rb +8 -0
- data/lib/rubocop/cop/rspec/include_examples.rb +39 -0
- data/lib/rubocop/cop/rspec/indexed_let.rb +2 -0
- data/lib/rubocop/cop/rspec/match_array.rb +1 -0
- data/lib/rubocop/cop/rspec/message_spies.rb +4 -0
- data/lib/rubocop/cop/rspec/mixin/metadata.rb +5 -8
- data/lib/rubocop/cop/rspec/nested_groups.rb +2 -2
- data/lib/rubocop/cop/rspec/no_expectation_example.rb +1 -1
- data/lib/rubocop/cop/rspec/pending.rb +1 -1
- data/lib/rubocop/cop/rspec/pending_without_reason.rb +2 -8
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +18 -8
- data/lib/rubocop/cop/rspec/receive_messages.rb +1 -2
- data/lib/rubocop/cop/rspec/redundant_around.rb +1 -1
- data/lib/rubocop/cop/rspec/return_from_stub.rb +5 -4
- data/lib/rubocop/cop/rspec/scattered_setup.rb +10 -2
- data/lib/rubocop/cop/rspec/sort_metadata.rb +22 -8
- data/lib/rubocop/cop/rspec/variable_definition.rb +1 -1
- data/lib/rubocop/cop/rspec/variable_name.rb +1 -1
- data/lib/rubocop/cop/rspec/verified_double_reference.rb +14 -53
- data/lib/rubocop/cop/rspec_cops.rb +1 -1
- data/lib/rubocop/rspec/config_formatter.rb +4 -9
- data/lib/rubocop/rspec/description_extractor.rb +2 -2
- data/lib/rubocop/rspec/hook.rb +3 -1
- data/lib/rubocop/rspec/language.rb +3 -6
- data/lib/rubocop/rspec/plugin.rb +37 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop/rspec/wording.rb +0 -2
- data/lib/rubocop/rspec.rb +0 -7
- data/lib/rubocop-rspec.rb +1 -3
- metadata +28 -10
- data/lib/rubocop/cop/rspec/string_as_instance_double_constant.rb +0 -45
- data/lib/rubocop/rspec/inject.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e4727f136d1a399d3108fd010c76ac61f7fce57e3c89cb2d97ad121d558af44
|
4
|
+
data.tar.gz: dcc8c7f61c420d5938807dae3a610f53c6be8c657687e38542f701db2aec4ce2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 651f8b53a0b70738f9dc084df5bdf471ce65ae4d7f0c2db8cc2eb557178fd541f317bee36ae062b8109aed72b452f69eb1c965db923d5d9875c86de9ab84f23e
|
7
|
+
data.tar.gz: f189ec83b4b663df4e3aca303f2f273fded6d5529e689d7f9421f379dd46203da95236a4f649414466b0f6050b0d9e7d952df003b4b63ed45722c1764fd1a094
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,27 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 3.6.0 (2025-04-18)
|
6
|
+
|
7
|
+
- Fix false positive in `RSpec/Pending`, where it would mark the default block `it` as an offense. ([@bquorning])
|
8
|
+
- Fix issue when `Style/ContextWording` is configured with a Prefix being interpreted as a boolean, like `on`. ([@sakuro])
|
9
|
+
- Add new `RSpec/IncludeExamples` cop to enforce using `it_behaves_like` over `include_examples`. ([@dvandersluis])
|
10
|
+
- Change `RSpec/ScatteredSetup` to allow `around` hooks to be scattered. ([@ydah])
|
11
|
+
- Fix an error `RSpec/ChangeByZero` cop when without expect block. ([@lee266])
|
12
|
+
- Fix a false positive for `RSpec/DescribedClass` when `SkipBlocks` is true and numblocks are used. ([@earlopain])
|
13
|
+
|
14
|
+
## 3.5.0 (2025-02-16)
|
15
|
+
|
16
|
+
- Don't let `RSpec/PredicateMatcher` replace `respond_to?` with two arguments with the RSpec `respond_to` matcher. ([@bquorning])
|
17
|
+
- Fix `RSpec/PredicateMatcher` support for `eql` and `equal` matchers. ([@bquorning])
|
18
|
+
- Pluginfy RuboCop RSpec. ([@koic])
|
19
|
+
|
20
|
+
## 3.4.0 (2025-01-20)
|
21
|
+
|
22
|
+
- Fix `RSpec/SortMetadata` cop to limit sorting to trailing metadata arguments. ([@cbliard])
|
23
|
+
- Replace `RSpec/StringAsInstanceDoubleConstant` with `RSpec/VerifiedDoubleReference` configured to only support constant class references. ([@corsonknowles])
|
24
|
+
- Fix `RSpec/EmptyExampleGroup` cop false positive when a simple conditional is used inside an iterator. ([@lovro-bikic])
|
25
|
+
|
5
26
|
## 3.3.0 (2024-12-12)
|
6
27
|
|
7
28
|
- Deprecate `top_level_group?` method from `TopLevelGroup` mixin as all of its callers were intentionally removed from `Rubocop/RSpec`. ([@corsonknowles])
|
@@ -93,7 +114,7 @@ Read more about how to upgrade in https://docs.rubocop.org/rubocop-rspec/upgrade
|
|
93
114
|
- Add new `RSpec/IsExpectedSpecify` cop. ([@ydah])
|
94
115
|
- Add new `RSpec/RepeatedSubjectCall` cop. ([@drcapulet])
|
95
116
|
- 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 `
|
117
|
+
- Support asserts with messages in `RSpec/BeEmpty`. ([@G-Rath])
|
97
118
|
- Fix a false positive for `RSpec/ExpectActual` when used with rspec-rails routing matchers. ([@naveg])
|
98
119
|
- Add configuration option `ResponseMethods` to `RSpec/Rails/HaveHttpStatus`. ([@ydah])
|
99
120
|
- Fix a false negative for `RSpec/DescribedClass` when class with constant. ([@ydah])
|
@@ -288,7 +309,7 @@ Read more about how to upgrade in https://docs.rubocop.org/rubocop-rspec/upgrade
|
|
288
309
|
## 2.13.0 (2022-09-12)
|
289
310
|
|
290
311
|
- Fix `RSpec/FilePath` cop missing mismatched expanded namespace. ([@sl4vr])
|
291
|
-
- Add new `AllowConsecutiveOneLiners` (default true) option for `
|
312
|
+
- Add new `AllowConsecutiveOneLiners` (default true) option for `RSpec/EmptyLineAfterHook` cop. ([@ngouy])
|
292
313
|
- Add autocorrect support for `RSpec/EmptyExampleGroup`. ([@r7kamura])
|
293
314
|
- Fix `RSpec/ChangeByZero` with compound expressions using `&` or `|` operators. ([@BrianHawley])
|
294
315
|
- Add `RSpec/NoExpectationExample`. ([@r7kamura])
|
@@ -986,9 +1007,11 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
986
1007
|
[@krororo]: https://github.com/krororo
|
987
1008
|
[@kuahyeow]: https://github.com/kuahyeow
|
988
1009
|
[@lazycoder9]: https://github.com/lazycoder9
|
1010
|
+
[@lee266]: https://github.com/lee266
|
989
1011
|
[@leoarnold]: https://github.com/leoarnold
|
990
1012
|
[@liberatys]: https://github.com/Liberatys
|
991
1013
|
[@lokhi]: https://github.com/lokhi
|
1014
|
+
[@lovro-bikic]: https://github.com/lovro-bikic
|
992
1015
|
[@luke-hill]: https://github.com/luke-hill
|
993
1016
|
[@m-yamashita01]: https://github.com/M-Yamashita01
|
994
1017
|
[@marocchino]: https://github.com/marocchino
|
@@ -1025,6 +1048,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
1025
1048
|
[@rrosenblum]: https://github.com/rrosenblum
|
1026
1049
|
[@rspeicher]: https://github.com/rspeicher
|
1027
1050
|
[@rst-j]: https://github.com/RST-J
|
1051
|
+
[@sakuro]: https://github.com/sakuro
|
1028
1052
|
[@samrjenkins]: https://github.com/samrjenkins
|
1029
1053
|
[@schmijos]: https://github.com/schmijos
|
1030
1054
|
[@seanpdoyle]: https://github.com/seanpdoyle
|
data/README.md
CHANGED
@@ -48,13 +48,13 @@ ways to do this:
|
|
48
48
|
Put this into your `.rubocop.yml`.
|
49
49
|
|
50
50
|
```yaml
|
51
|
-
|
51
|
+
plugins: rubocop-rspec
|
52
52
|
```
|
53
53
|
|
54
54
|
Alternatively, use the following array notation when specifying multiple extensions.
|
55
55
|
|
56
56
|
```yaml
|
57
|
-
|
57
|
+
plugins:
|
58
58
|
- rubocop-other-extension
|
59
59
|
- rubocop-rspec
|
60
60
|
```
|
@@ -62,17 +62,20 @@ require:
|
|
62
62
|
Now you can run `rubocop` and it will automatically load the RuboCop RSpec
|
63
63
|
cops together with the standard cops.
|
64
64
|
|
65
|
+
> [!NOTE]
|
66
|
+
> The plugin system is supported in RuboCop 1.72+. In earlier versions, use `require` instead of `plugins`.
|
67
|
+
|
65
68
|
### Command line
|
66
69
|
|
67
70
|
```bash
|
68
|
-
rubocop --
|
71
|
+
rubocop --plugin rubocop-rspec
|
69
72
|
```
|
70
73
|
|
71
74
|
### Rake task
|
72
75
|
|
73
76
|
```ruby
|
74
77
|
RuboCop::RakeTask.new do |task|
|
75
|
-
task.
|
78
|
+
task.plugins << 'rubocop-rspec'
|
76
79
|
end
|
77
80
|
```
|
78
81
|
|
data/config/default.yml
CHANGED
@@ -532,6 +532,12 @@ RSpec/ImplicitSubject:
|
|
532
532
|
VersionChanged: '2.13'
|
533
533
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitSubject
|
534
534
|
|
535
|
+
RSpec/IncludeExamples:
|
536
|
+
Description: Checks for usage of `include_examples`.
|
537
|
+
Enabled: pending
|
538
|
+
VersionAdded: '3.6'
|
539
|
+
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/IncludeExamples
|
540
|
+
|
535
541
|
RSpec/IndexedLet:
|
536
542
|
Description: Do not set up test data using indexes (e.g., `item_1`, `item_2`).
|
537
543
|
Enabled: true
|
@@ -930,13 +936,6 @@ RSpec/SpecFilePathSuffix:
|
|
930
936
|
- "**/spec/**/*"
|
931
937
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SpecFilePathSuffix
|
932
938
|
|
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
939
|
RSpec/StubbedMock:
|
941
940
|
Description: Checks that message expectations do not have a configured response.
|
942
941
|
Enabled: true
|
@@ -995,12 +994,8 @@ RSpec/VerifiedDoubleReference:
|
|
995
994
|
Description: Checks for consistent verified double reference style.
|
996
995
|
Enabled: true
|
997
996
|
SafeAutoCorrect: false
|
998
|
-
EnforcedStyle: constant
|
999
|
-
SupportedStyles:
|
1000
|
-
- constant
|
1001
|
-
- string
|
1002
997
|
VersionAdded: 2.10.0
|
1003
|
-
VersionChanged: '
|
998
|
+
VersionChanged: '3.4'
|
1004
999
|
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubleReference
|
1005
1000
|
|
1006
1001
|
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
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
|
46
46
|
# @!method eql_type_with_identity(node)
|
47
47
|
def_node_matcher :eql_type_with_identity, <<~PATTERN
|
48
|
-
(send _ :to $(send nil? :eql {
|
48
|
+
(send _ :to $(send nil? :eql {boolean int float sym nil}))
|
49
49
|
PATTERN
|
50
50
|
|
51
51
|
def on_send(node)
|
@@ -101,8 +101,9 @@ module RuboCop
|
|
101
101
|
|
102
102
|
private
|
103
103
|
|
104
|
-
# rubocop:disable Metrics/MethodLength
|
105
104
|
def register_offense(node, change_node)
|
105
|
+
return unless node.parent.send_type?
|
106
|
+
|
106
107
|
if compound_expectations?(node)
|
107
108
|
add_offense(node,
|
108
109
|
message: message_compound(change_node)) do |corrector|
|
@@ -115,11 +116,9 @@ module RuboCop
|
|
115
116
|
end
|
116
117
|
end
|
117
118
|
end
|
118
|
-
# rubocop:enable Metrics/MethodLength
|
119
119
|
|
120
120
|
def compound_expectations?(node)
|
121
|
-
node.parent.
|
122
|
-
%i[and or & |].include?(node.parent.method_name)
|
121
|
+
%i[and or & |].include?(node.parent.method_name)
|
123
122
|
end
|
124
123
|
|
125
124
|
def message(change_node)
|
@@ -115,7 +115,12 @@ module RuboCop
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def prefixes
|
118
|
-
Array(cop_config.fetch('Prefixes', []))
|
118
|
+
Array(cop_config.fetch('Prefixes', [])).tap do |prefixes|
|
119
|
+
non_strings = prefixes.reject { |pre| pre.is_a?(String) }
|
120
|
+
unless non_strings.empty?
|
121
|
+
raise "Non-string prefixes #{non_strings.inspect} detected."
|
122
|
+
end
|
123
|
+
end
|
119
124
|
end
|
120
125
|
end
|
121
126
|
end
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
83
83
|
|
84
84
|
# @!method rspec_block?(node)
|
85
85
|
def_node_matcher :rspec_block?,
|
86
|
-
'(
|
86
|
+
'(any_block (send #rspec? #ALL.all ...) ...)'
|
87
87
|
|
88
88
|
# @!method scope_changing_syntax?(node)
|
89
89
|
def_node_matcher :scope_changing_syntax?, '{def class module}'
|
@@ -153,7 +153,9 @@ module RuboCop
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def skippable_block?(node)
|
156
|
-
|
156
|
+
return false unless cop_config['SkipBlocks']
|
157
|
+
|
158
|
+
node.any_block_type? && !rspec_block?(node)
|
157
159
|
end
|
158
160
|
|
159
161
|
def only_static_constants?
|
@@ -24,7 +24,7 @@ module RuboCop
|
|
24
24
|
|
25
25
|
# @!method include_rspec_blocks?(node)
|
26
26
|
def_node_search :include_rspec_blocks?, <<~PATTERN
|
27
|
-
(
|
27
|
+
(any_block (send #explicit_rspec? #ExampleGroups.all ...) ...)
|
28
28
|
PATTERN
|
29
29
|
|
30
30
|
def on_module(node)
|
@@ -130,13 +130,14 @@ 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
|
}
|
136
137
|
PATTERN
|
137
138
|
|
138
139
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
139
|
-
return if node.each_ancestor(:
|
140
|
+
return if node.each_ancestor(:any_def).any?
|
140
141
|
return if node.each_ancestor(:block).any? { |block| example?(block) }
|
141
142
|
|
142
143
|
example_group_body(node) do |body|
|
@@ -154,7 +155,7 @@ module RuboCop
|
|
154
155
|
return true unless body
|
155
156
|
return false if conditionals_with_examples?(body)
|
156
157
|
|
157
|
-
if body.
|
158
|
+
if body.type?(:if, :case)
|
158
159
|
!examples_in_branches?(body)
|
159
160
|
else
|
160
161
|
!examples?(body)
|
@@ -162,7 +163,7 @@ module RuboCop
|
|
162
163
|
end
|
163
164
|
|
164
165
|
def conditionals_with_examples?(body)
|
165
|
-
return false unless body.
|
166
|
+
return false unless body.type?(:begin, :case)
|
166
167
|
|
167
168
|
body.each_descendant(:if, :case).any? do |condition_node|
|
168
169
|
examples_in_branches?(condition_node)
|
@@ -170,7 +171,8 @@ module RuboCop
|
|
170
171
|
end
|
171
172
|
|
172
173
|
def examples_in_branches?(condition_node)
|
173
|
-
return false
|
174
|
+
return false unless condition_node
|
175
|
+
return false unless condition_node.type?(:if, :case)
|
174
176
|
|
175
177
|
condition_node.branches.any? { |branch| examples?(branch) }
|
176
178
|
end
|
@@ -67,7 +67,6 @@ module RuboCop
|
|
67
67
|
} ...) ...)
|
68
68
|
PATTERN
|
69
69
|
|
70
|
-
# rubocop:disable Metrics/MethodLength
|
71
70
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
72
71
|
it_description(node) do |description_node, message|
|
73
72
|
if message.match?(SHOULD_PREFIX)
|
@@ -82,7 +81,6 @@ module RuboCop
|
|
82
81
|
end
|
83
82
|
end
|
84
83
|
end
|
85
|
-
# rubocop:enable Metrics/MethodLength
|
86
84
|
|
87
85
|
private
|
88
86
|
|
@@ -128,7 +126,7 @@ module RuboCop
|
|
128
126
|
node.node_parts.map { |child_node| text(child_node) }.join
|
129
127
|
when :str
|
130
128
|
node.value
|
131
|
-
|
129
|
+
else
|
132
130
|
node.source
|
133
131
|
end
|
134
132
|
end
|
@@ -5,11 +5,30 @@ module RuboCop
|
|
5
5
|
module RSpec
|
6
6
|
# Checks for consistent style of change matcher.
|
7
7
|
#
|
8
|
-
# Enforces either passing
|
9
|
-
# or
|
8
|
+
# Enforces either passing a receiver and message as method arguments,
|
9
|
+
# or a block.
|
10
10
|
#
|
11
11
|
# This cop can be configured using the `EnforcedStyle` option.
|
12
12
|
#
|
13
|
+
# @safety
|
14
|
+
# Autocorrection is unsafe because `method_call` style calls the
|
15
|
+
# receiver *once* and sends the message to it before and after
|
16
|
+
# calling the `expect` block, whereas `block` style calls the
|
17
|
+
# expression *twice*, including the receiver.
|
18
|
+
#
|
19
|
+
# If your receiver is dynamic (e.g., the result of a method call) and
|
20
|
+
# you expect it to be called before and after the `expect` block,
|
21
|
+
# changing from `block` to `method_call` style may break your test.
|
22
|
+
#
|
23
|
+
# [source,ruby]
|
24
|
+
# ----
|
25
|
+
# expect { run }.to change { my_method.message }
|
26
|
+
# # `my_method` is called before and after `run`
|
27
|
+
#
|
28
|
+
# expect { run }.to change(my_method, :message)
|
29
|
+
# # `my_method` is called once, but `message` is called on it twice
|
30
|
+
# ----
|
31
|
+
#
|
13
32
|
# @example `EnforcedStyle: method_call` (default)
|
14
33
|
# # bad
|
15
34
|
# expect { run }.to change { Foo.bar }
|
@@ -29,12 +29,6 @@ module RuboCop
|
|
29
29
|
# describe 'test' do; end
|
30
30
|
#
|
31
31
|
# # bad
|
32
|
-
# fdescribe 'test' do; end
|
33
|
-
#
|
34
|
-
# # good
|
35
|
-
# describe 'test' do; end
|
36
|
-
#
|
37
|
-
# # bad
|
38
32
|
# shared_examples 'test', focus: true do; end
|
39
33
|
#
|
40
34
|
# # good
|
@@ -79,25 +73,29 @@ module RuboCop
|
|
79
73
|
PATTERN
|
80
74
|
|
81
75
|
def on_send(node)
|
82
|
-
return if node.chained? || node.each_ancestor(:
|
76
|
+
return if node.chained? || node.each_ancestor(:any_def).any?
|
83
77
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
correct_send(corrector, focus)
|
90
|
-
end
|
78
|
+
if focused_block?(node)
|
79
|
+
on_focused_block(node)
|
80
|
+
else
|
81
|
+
metadata(node) do |focus|
|
82
|
+
on_metadata(focus)
|
91
83
|
end
|
92
84
|
end
|
93
85
|
end
|
94
86
|
|
95
87
|
private
|
96
88
|
|
97
|
-
def
|
98
|
-
|
89
|
+
def on_focused_block(node)
|
90
|
+
add_offense(node) do |corrector|
|
91
|
+
correct_send(corrector, node)
|
92
|
+
end
|
93
|
+
end
|
99
94
|
|
100
|
-
|
95
|
+
def on_metadata(node)
|
96
|
+
add_offense(node) do |corrector|
|
97
|
+
corrector.remove(with_surrounding(node))
|
98
|
+
end
|
101
99
|
end
|
102
100
|
|
103
101
|
def with_surrounding(focus)
|
@@ -67,12 +67,12 @@ module RuboCop
|
|
67
67
|
|
68
68
|
# @!method scoped_hook(node)
|
69
69
|
def_node_matcher :scoped_hook, <<~PATTERN
|
70
|
-
(
|
70
|
+
(any_block $(send _ #Hooks.all (sym ${:each :example})) ...)
|
71
71
|
PATTERN
|
72
72
|
|
73
73
|
# @!method unscoped_hook(node)
|
74
74
|
def_node_matcher :unscoped_hook, <<~PATTERN
|
75
|
-
(
|
75
|
+
(any_block $(send _ #Hooks.all) ...)
|
76
76
|
PATTERN
|
77
77
|
|
78
78
|
def on_block(node)
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
|
47
47
|
ENFORCED_REPLACEMENTS = alternatives.merge(alternatives.invert).freeze
|
48
48
|
|
49
|
-
def on_send(node)
|
49
|
+
def on_send(node)
|
50
50
|
return unless (source_range = offending_expect(node))
|
51
51
|
|
52
52
|
expectation_source = source_range.source
|
@@ -69,13 +69,13 @@ module RuboCop
|
|
69
69
|
def offending_expect(node)
|
70
70
|
case implicit_expect(node)
|
71
71
|
when :is_expected
|
72
|
-
|
72
|
+
range_for_is_expected(node.loc)
|
73
73
|
when :should, :should_not
|
74
74
|
node.loc.selector
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
def
|
78
|
+
def range_for_is_expected(source_map)
|
79
79
|
Parser::Source::Range.new(
|
80
80
|
source_map.expression.source_buffer,
|
81
81
|
source_map.expression.begin_pos,
|
@@ -107,6 +107,10 @@ module RuboCop
|
|
107
107
|
corrector.replace(node.location.selector, 'expect(subject).to')
|
108
108
|
when :should_not
|
109
109
|
corrector.replace(node.location.selector, 'expect(subject).not_to')
|
110
|
+
else
|
111
|
+
# :nocov:
|
112
|
+
:noop
|
113
|
+
# :nocov:
|
110
114
|
end
|
111
115
|
end
|
112
116
|
|
@@ -129,6 +133,10 @@ module RuboCop
|
|
129
133
|
implicit_subject_in_non_its_and_non_single_line?(node)
|
130
134
|
when :single_statement_only
|
131
135
|
implicit_subject_in_non_its_and_non_single_statement?(node)
|
136
|
+
else
|
137
|
+
# :nocov:
|
138
|
+
:noop
|
139
|
+
# :nocov:
|
132
140
|
end
|
133
141
|
end
|
134
142
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks for usage of `include_examples`.
|
7
|
+
#
|
8
|
+
# `include_examples`, unlike `it_behaves_like`, does not create its
|
9
|
+
# own context. As such, using `subject`, `let`, `before`/`after`, etc.
|
10
|
+
# within shared examples included with `include_examples` can have
|
11
|
+
# unexpected behavior and side effects.
|
12
|
+
#
|
13
|
+
# Prefer using `it_behaves_like` instead.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# # bad
|
17
|
+
# include_examples 'examples'
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# it_behaves_like 'examples'
|
21
|
+
#
|
22
|
+
class IncludeExamples < Base
|
23
|
+
extend AutoCorrector
|
24
|
+
|
25
|
+
MSG = 'Prefer `it_behaves_like` over `include_examples`.'
|
26
|
+
|
27
|
+
RESTRICT_ON_SEND = %i[include_examples].freeze
|
28
|
+
|
29
|
+
def on_send(node)
|
30
|
+
selector = node.loc.selector
|
31
|
+
|
32
|
+
add_offense(selector) do |corrector|
|
33
|
+
corrector.replace(selector, 'it_behaves_like')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -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
|
@@ -133,8 +133,8 @@ module RuboCop
|
|
133
133
|
|
134
134
|
def count_up_nesting?(node, example_group)
|
135
135
|
example_group &&
|
136
|
-
|
137
|
-
!allowed_groups.include?(node.method_name.to_s)
|
136
|
+
node.block_type? &&
|
137
|
+
!allowed_groups.include?(node.method_name.to_s)
|
138
138
|
end
|
139
139
|
|
140
140
|
def message(nesting)
|
@@ -65,7 +65,7 @@ module RuboCop
|
|
65
65
|
# @param [RuboCop::AST::Node] node
|
66
66
|
# @return [Boolean]
|
67
67
|
def_node_matcher :regular_or_focused_example?, <<~PATTERN
|
68
|
-
(
|
68
|
+
(any_block (send nil? {#Examples.regular #Examples.focused} ...) ...)
|
69
69
|
PATTERN
|
70
70
|
|
71
71
|
# @!method includes_expectation?(node)
|