rubocop-rspec 1.39.0 → 1.40.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 +15 -0
- data/README.md +1 -61
- data/config/default.yml +136 -18
- data/lib/rubocop-rspec.rb +1 -0
- data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +26 -11
- data/lib/rubocop/cop/rspec/cop.rb +8 -28
- data/lib/rubocop/cop/rspec/file_path.rb +29 -3
- data/lib/rubocop/cop/rspec/rails/http_status.rb +2 -0
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +11 -1
- data/lib/rubocop/cop/rspec/shared_examples.rb +1 -0
- data/lib/rubocop/cop/rspec/subject_stub.rb +25 -47
- data/lib/rubocop/cop/rspec/variable_definition.rb +56 -0
- data/lib/rubocop/cop/rspec/variable_name.rb +47 -0
- data/lib/rubocop/cop/rspec_cops.rb +2 -0
- data/lib/rubocop/rspec/description_extractor.rb +2 -6
- data/lib/rubocop/rspec/variable.rb +16 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59e10874a1394fa4741d2f03d4e3fc99fc86a708b8973024be0e33f568e20b0a
|
4
|
+
data.tar.gz: b33b46623283aebafe40edd9509c58cabe052a4602fdebd97f69250e9f7ea206
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e109509a667750018f86fb3fbe6e05cce32a22fb99dde8bcd39ab4bdecb688af372baea3e05b1a156074b8c1f295ae129415356510c72a72face5b49e51b492
|
7
|
+
data.tar.gz: fa38c3aa5e06adc57a1ca991e2dc42cb9511580a4214089323c1f76403f923940f845c709ff0393805035766184b2855fab4d31b4af11b5cdea9f278cdf2d87c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 1.40.0 (2020-06-11)
|
6
|
+
|
7
|
+
* Add new `RSpec/VariableName` cop. ([@tejasbubane][])
|
8
|
+
* Add new `RSpec/VariableDefinition` cop. ([@tejasbubane][])
|
9
|
+
* Expand `Capybara/VisibilityMatcher` to support more than just `have_selector`. ([@twalpole][])
|
10
|
+
* Add new `SpecSuffixOnly` option to `RSpec/FilePath` cop. ([@zdennis][])
|
11
|
+
* Allow `RSpec/RepeatedExampleGroupBody` to differ only by described_class. ([@robotdana][])
|
12
|
+
* Fix `RSpec/FilePath` detection across sibling directories. ([@rolfschmidt][])
|
13
|
+
* Improve the performance of `RSpec/SubjectStub` by an order of magnitude. ([@andrykonchin][])
|
14
|
+
|
5
15
|
## 1.39.0 (2020-05-01)
|
6
16
|
|
7
17
|
* Fix `RSpec/FilePath` detection when absolute path includes test subject. ([@eitoball][])
|
@@ -503,3 +513,8 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
503
513
|
[@aried3r]: https://github.com/aried3r
|
504
514
|
[@AlexWayfer]: https://github.com/AlexWayfer
|
505
515
|
[@tejasbubane]: https://github.com/tejasbubane
|
516
|
+
[@twalpole]: https://github.com/twalpole
|
517
|
+
[@zdennis]: https://github.com/zdennis
|
518
|
+
[@robotdana]: https://github.com/robotdana
|
519
|
+
[@rolfschmidt]: https://github.com/rolfschmidt
|
520
|
+
[@andrykonchin]: https://github.com/andrykonchin
|
data/README.md
CHANGED
@@ -67,27 +67,7 @@ rubocop-rspec is available on Code Climate as part of the rubocop engine. [Learn
|
|
67
67
|
|
68
68
|
## Documentation
|
69
69
|
|
70
|
-
You can read more about RuboCop-RSpec in its [official manual](
|
71
|
-
|
72
|
-
## Inspecting files that don't end with `_spec.rb`
|
73
|
-
|
74
|
-
By default, `rubocop-rspec` only inspects code within paths ending in `_spec.rb` or including `spec/`. You can override this setting in your config file by specifying one or more patterns:
|
75
|
-
|
76
|
-
```yaml
|
77
|
-
# Inspect all files
|
78
|
-
AllCops:
|
79
|
-
RSpec:
|
80
|
-
Patterns:
|
81
|
-
- '.+'
|
82
|
-
```
|
83
|
-
|
84
|
-
```yaml
|
85
|
-
# Inspect only files ending with `_test.rb`
|
86
|
-
AllCops:
|
87
|
-
RSpec:
|
88
|
-
Patterns:
|
89
|
-
- '_test.rb$'
|
90
|
-
```
|
70
|
+
You can read more about RuboCop-RSpec in its [official manual](https://docs.rubocop.org/rubocop-rspec).
|
91
71
|
|
92
72
|
## The Cops
|
93
73
|
|
@@ -104,46 +84,6 @@ RSpec/FilePath:
|
|
104
84
|
- spec/my_poorly_named_spec_file.rb
|
105
85
|
```
|
106
86
|
|
107
|
-
## Non-goals of RuboCop RSpec
|
108
|
-
|
109
|
-
### Enforcing `should` vs. `expect` syntax
|
110
|
-
|
111
|
-
Enforcing
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
expect(calculator.compute(line_item)).to eq(5)
|
115
|
-
```
|
116
|
-
|
117
|
-
over
|
118
|
-
|
119
|
-
```ruby
|
120
|
-
calculator.compute(line_item).should == 5
|
121
|
-
```
|
122
|
-
|
123
|
-
is a feature of RSpec itself – you can read about it in the [RSpec Documentation](https://relishapp.com/rspec/rspec-expectations/docs/syntax-configuration#disable-should-syntax)
|
124
|
-
|
125
|
-
### Enforcing an explicit RSpec receiver for top-level methods (disabling monkey patching)
|
126
|
-
|
127
|
-
Enforcing
|
128
|
-
|
129
|
-
```ruby
|
130
|
-
RSpec.describe MyClass do
|
131
|
-
...
|
132
|
-
end
|
133
|
-
```
|
134
|
-
|
135
|
-
over
|
136
|
-
|
137
|
-
```ruby
|
138
|
-
describe MyClass do
|
139
|
-
...
|
140
|
-
end
|
141
|
-
```
|
142
|
-
|
143
|
-
can be achieved using RSpec's `disable_monkey_patching!` method, which you can read more about in the [RSpec Documentation](https://relishapp.com/rspec/rspec-core/v/3-7/docs/configuration/zero-monkey-patching-mode#monkey-patched-methods-are-undefined-with-%60disable-monkey-patching!%60). This will also prevent `should` from being defined on every object in your system.
|
144
|
-
|
145
|
-
Before disabling `should` you will need all your specs to use the `expect` syntax. You can use [Transpec](http://yujinakayama.me/transpec/), which will do the conversion for you.
|
146
|
-
|
147
87
|
## Contributing
|
148
88
|
|
149
89
|
Checkout the [contribution guidelines](.github/CONTRIBUTING.md).
|
data/config/default.yml
CHANGED
@@ -13,31 +13,37 @@ AllCops:
|
|
13
13
|
RSpec/AlignLeftLetBrace:
|
14
14
|
Description: Checks that left braces for adjacent single line lets are aligned.
|
15
15
|
Enabled: false
|
16
|
+
VersionAdded: '1.16'
|
16
17
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AlignLeftLetBrace
|
17
18
|
|
18
19
|
RSpec/AlignRightLetBrace:
|
19
20
|
Description: Checks that right braces for adjacent single line lets are aligned.
|
20
21
|
Enabled: false
|
22
|
+
VersionAdded: '1.16'
|
21
23
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AlignRightLetBrace
|
22
24
|
|
23
25
|
RSpec/AnyInstance:
|
24
26
|
Description: Check that instances are not being stubbed globally.
|
25
27
|
Enabled: true
|
28
|
+
VersionAdded: '1.4'
|
26
29
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AnyInstance
|
27
30
|
|
28
31
|
RSpec/AroundBlock:
|
29
32
|
Description: Checks that around blocks actually run the test.
|
30
33
|
Enabled: true
|
34
|
+
VersionAdded: '1.11'
|
31
35
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AroundBlock
|
32
36
|
|
33
37
|
RSpec/Be:
|
34
38
|
Description: Check for expectations where `be` is used without argument.
|
35
39
|
Enabled: true
|
40
|
+
VersionAdded: '1.25'
|
36
41
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Be
|
37
42
|
|
38
43
|
RSpec/BeEql:
|
39
44
|
Description: Check for expectations where `be(...)` can replace `eql(...)`.
|
40
45
|
Enabled: true
|
46
|
+
VersionAdded: '1.7'
|
41
47
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeEql
|
42
48
|
|
43
49
|
RSpec/BeforeAfterAll:
|
@@ -47,11 +53,13 @@ RSpec/BeforeAfterAll:
|
|
47
53
|
- spec/spec_helper.rb
|
48
54
|
- spec/rails_helper.rb
|
49
55
|
- spec/support/**/*.rb
|
56
|
+
VersionAdded: '1.12'
|
50
57
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeforeAfterAll
|
51
58
|
|
52
59
|
RSpec/ContextMethod:
|
53
60
|
Description: "`context` should not be used for specifying methods."
|
54
61
|
Enabled: true
|
62
|
+
VersionAdded: '1.36'
|
55
63
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ContextMethod
|
56
64
|
|
57
65
|
RSpec/ContextWording:
|
@@ -61,86 +69,103 @@ RSpec/ContextWording:
|
|
61
69
|
- when
|
62
70
|
- with
|
63
71
|
- without
|
72
|
+
VersionAdded: '1.20'
|
73
|
+
VersionChanged: 1.20.1
|
64
74
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ContextWording
|
65
75
|
|
66
76
|
RSpec/DescribeClass:
|
67
77
|
Description: Check that the first argument to the top level describe is a constant.
|
68
78
|
Enabled: true
|
79
|
+
VersionAdded: '1.0'
|
69
80
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass
|
70
81
|
|
71
82
|
RSpec/DescribeMethod:
|
72
83
|
Description: Checks that the second argument to `describe` specifies a method.
|
73
84
|
Enabled: true
|
85
|
+
VersionAdded: '1.0'
|
74
86
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeMethod
|
75
87
|
|
76
88
|
RSpec/DescribeSymbol:
|
77
89
|
Description: Avoid describing symbols.
|
78
90
|
Enabled: true
|
91
|
+
VersionAdded: '1.15'
|
79
92
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeSymbol
|
80
93
|
|
81
94
|
RSpec/DescribedClass:
|
82
95
|
Description: Checks that tests use `described_class`.
|
83
|
-
SkipBlocks: false
|
84
96
|
Enabled: true
|
97
|
+
SkipBlocks: false
|
85
98
|
EnforcedStyle: described_class
|
86
99
|
SupportedStyles:
|
87
100
|
- described_class
|
88
101
|
- explicit
|
102
|
+
SafeAutoCorrect: false
|
103
|
+
VersionAdded: '1.0'
|
104
|
+
VersionChanged: '1.11'
|
89
105
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribedClass
|
90
106
|
|
91
107
|
RSpec/DescribedClassModuleWrapping:
|
92
108
|
Description: Avoid opening modules and defining specs within them.
|
93
109
|
Enabled: false
|
110
|
+
VersionAdded: '1.37'
|
94
111
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribedClassModuleWrapping
|
95
112
|
|
96
113
|
RSpec/Dialect:
|
97
114
|
Description: This cop enforces custom RSpec dialects.
|
98
115
|
Enabled: false
|
99
116
|
PreferredMethods: {}
|
117
|
+
VersionAdded: '1.33'
|
100
118
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Dialect
|
101
119
|
|
102
120
|
RSpec/EmptyExampleGroup:
|
103
121
|
Description: Checks if an example group does not include any tests.
|
104
122
|
Enabled: true
|
105
123
|
CustomIncludeMethods: []
|
124
|
+
VersionAdded: '1.7'
|
106
125
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyExampleGroup
|
107
126
|
|
108
127
|
RSpec/EmptyHook:
|
109
128
|
Description: Checks for empty before and after hooks.
|
110
129
|
Enabled: true
|
111
|
-
VersionAdded: 1.39
|
130
|
+
VersionAdded: '1.39'
|
112
131
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyHook
|
113
132
|
|
114
133
|
RSpec/EmptyLineAfterExample:
|
115
134
|
Description: Checks if there is an empty line after example blocks.
|
116
135
|
Enabled: true
|
117
136
|
AllowConsecutiveOneLiners: true
|
137
|
+
VersionAdded: '1.36'
|
118
138
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterExample
|
119
139
|
|
120
140
|
RSpec/EmptyLineAfterExampleGroup:
|
121
141
|
Description: Checks if there is an empty line after example group blocks.
|
122
142
|
Enabled: true
|
143
|
+
VersionAdded: '1.27'
|
123
144
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterExampleGroup
|
124
145
|
|
125
146
|
RSpec/EmptyLineAfterFinalLet:
|
126
147
|
Description: Checks if there is an empty line after the last let block.
|
127
148
|
Enabled: true
|
149
|
+
VersionAdded: '1.14'
|
128
150
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterFinalLet
|
129
151
|
|
130
152
|
RSpec/EmptyLineAfterHook:
|
131
153
|
Description: Checks if there is an empty line after hook blocks.
|
132
154
|
Enabled: true
|
155
|
+
VersionAdded: '1.27'
|
133
156
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterHook
|
134
157
|
|
135
158
|
RSpec/EmptyLineAfterSubject:
|
136
159
|
Description: Checks if there is an empty line after subject block.
|
137
160
|
Enabled: true
|
161
|
+
VersionAdded: '1.14'
|
138
162
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/EmptyLineAfterSubject
|
139
163
|
|
140
164
|
RSpec/ExampleLength:
|
141
165
|
Description: Checks for long examples.
|
142
166
|
Enabled: true
|
143
167
|
Max: 5
|
168
|
+
VersionAdded: '1.5'
|
144
169
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleLength
|
145
170
|
|
146
171
|
RSpec/ExampleWithoutDescription:
|
@@ -151,6 +176,7 @@ RSpec/ExampleWithoutDescription:
|
|
151
176
|
- always_allow
|
152
177
|
- single_line_only
|
153
178
|
- disallow
|
179
|
+
VersionAdded: '1.22'
|
154
180
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWithoutDescription
|
155
181
|
|
156
182
|
RSpec/ExampleWording:
|
@@ -162,6 +188,8 @@ RSpec/ExampleWording:
|
|
162
188
|
have: has
|
163
189
|
HAVE: HAS
|
164
190
|
IgnoredWords: []
|
191
|
+
VersionAdded: '1.0'
|
192
|
+
VersionChanged: '1.2'
|
165
193
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWording
|
166
194
|
|
167
195
|
RSpec/ExpectActual:
|
@@ -169,6 +197,7 @@ RSpec/ExpectActual:
|
|
169
197
|
Enabled: true
|
170
198
|
Exclude:
|
171
199
|
- spec/routing/**/*
|
200
|
+
VersionAdded: '1.7'
|
172
201
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectActual
|
173
202
|
|
174
203
|
RSpec/ExpectChange:
|
@@ -178,30 +207,37 @@ RSpec/ExpectChange:
|
|
178
207
|
SupportedStyles:
|
179
208
|
- method_call
|
180
209
|
- block
|
210
|
+
VersionAdded: '1.22'
|
181
211
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectChange
|
182
212
|
|
183
213
|
RSpec/ExpectInHook:
|
184
|
-
Enabled: true
|
185
214
|
Description: Do not use `expect` in hooks such as `before`.
|
215
|
+
Enabled: true
|
216
|
+
VersionAdded: '1.16'
|
186
217
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectInHook
|
187
218
|
|
188
219
|
RSpec/ExpectOutput:
|
189
220
|
Description: Checks for opportunities to use `expect { ... }.to output`.
|
190
221
|
Enabled: true
|
222
|
+
VersionAdded: '1.10'
|
191
223
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExpectOutput
|
192
224
|
|
193
225
|
RSpec/FilePath:
|
194
|
-
Description: Checks that spec file paths are consistent
|
226
|
+
Description: Checks that spec file paths are consistent and well-formed.
|
195
227
|
Enabled: true
|
196
228
|
CustomTransform:
|
197
229
|
RuboCop: rubocop
|
198
230
|
RSpec: rspec
|
199
231
|
IgnoreMethods: false
|
232
|
+
SpecSuffixOnly: false
|
233
|
+
VersionAdded: '1.2'
|
234
|
+
VersionChanged: '1.40'
|
200
235
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FilePath
|
201
236
|
|
202
237
|
RSpec/Focus:
|
203
238
|
Description: Checks if examples are focused.
|
204
239
|
Enabled: true
|
240
|
+
VersionAdded: '1.5'
|
205
241
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Focus
|
206
242
|
|
207
243
|
RSpec/HookArgument:
|
@@ -212,16 +248,19 @@ RSpec/HookArgument:
|
|
212
248
|
- implicit
|
213
249
|
- each
|
214
250
|
- example
|
251
|
+
VersionAdded: '1.7'
|
215
252
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/HookArgument
|
216
253
|
|
217
254
|
RSpec/HooksBeforeExamples:
|
218
|
-
Enabled: true
|
219
255
|
Description: Checks for before/around/after hooks that come after an example.
|
256
|
+
Enabled: true
|
257
|
+
VersionAdded: '1.29'
|
220
258
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/HooksBeforeExamples
|
221
259
|
|
222
260
|
RSpec/ImplicitBlockExpectation:
|
223
261
|
Description: Check that implicit block expectation syntax is not used.
|
224
262
|
Enabled: true
|
263
|
+
VersionAdded: '1.35'
|
225
264
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitBlockExpectation
|
226
265
|
|
227
266
|
RSpec/ImplicitExpect:
|
@@ -231,32 +270,39 @@ RSpec/ImplicitExpect:
|
|
231
270
|
SupportedStyles:
|
232
271
|
- is_expected
|
233
272
|
- should
|
273
|
+
VersionAdded: '1.8'
|
234
274
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitExpect
|
235
275
|
|
236
276
|
RSpec/ImplicitSubject:
|
237
|
-
Enabled: true
|
238
277
|
Description: Checks for usage of implicit subject (`is_expected` / `should`).
|
278
|
+
Enabled: true
|
239
279
|
EnforcedStyle: single_line_only
|
240
280
|
SupportedStyles:
|
241
281
|
- single_line_only
|
242
282
|
- single_statement_only
|
243
283
|
- disallow
|
284
|
+
VersionAdded: '1.29'
|
285
|
+
VersionChanged: '1.30'
|
244
286
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitSubject
|
245
287
|
|
246
288
|
RSpec/InstanceSpy:
|
247
289
|
Description: Checks for `instance_double` used with `have_received`.
|
248
290
|
Enabled: true
|
291
|
+
VersionAdded: '1.12'
|
249
292
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InstanceSpy
|
250
293
|
|
251
294
|
RSpec/InstanceVariable:
|
252
295
|
Description: Checks for instance variable usage in specs.
|
253
|
-
AssignmentOnly: false
|
254
296
|
Enabled: true
|
297
|
+
AssignmentOnly: false
|
298
|
+
VersionAdded: '1.0'
|
299
|
+
VersionChanged: '1.7'
|
255
300
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InstanceVariable
|
256
301
|
|
257
302
|
RSpec/InvalidPredicateMatcher:
|
258
303
|
Description: Checks invalid usage for predicate matcher.
|
259
304
|
Enabled: true
|
305
|
+
VersionAdded: '1.16'
|
260
306
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/InvalidPredicateMatcher
|
261
307
|
|
262
308
|
RSpec/ItBehavesLike:
|
@@ -266,36 +312,45 @@ RSpec/ItBehavesLike:
|
|
266
312
|
SupportedStyles:
|
267
313
|
- it_behaves_like
|
268
314
|
- it_should_behave_like
|
315
|
+
VersionAdded: '1.13'
|
269
316
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ItBehavesLike
|
270
317
|
|
271
318
|
RSpec/IteratedExpectation:
|
272
319
|
Description: Check that `all` matcher is used instead of iterating over an array.
|
273
320
|
Enabled: true
|
321
|
+
VersionAdded: '1.14'
|
274
322
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/IteratedExpectation
|
275
323
|
|
276
324
|
RSpec/LeadingSubject:
|
277
325
|
Description: Enforce that subject is the first definition in the test.
|
278
326
|
Enabled: true
|
327
|
+
VersionAdded: '1.7'
|
328
|
+
VersionChanged: '1.14'
|
279
329
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LeadingSubject
|
280
330
|
|
281
331
|
RSpec/LeakyConstantDeclaration:
|
282
332
|
Description: Checks that no class, module, or constant is declared.
|
283
333
|
Enabled: true
|
334
|
+
VersionAdded: '1.35'
|
284
335
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LeakyConstantDeclaration
|
285
336
|
|
286
337
|
RSpec/LetBeforeExamples:
|
287
338
|
Description: Checks for `let` definitions that come after an example.
|
288
339
|
Enabled: true
|
340
|
+
VersionAdded: '1.16'
|
341
|
+
VersionChanged: '1.22'
|
289
342
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LetBeforeExamples
|
290
343
|
|
291
344
|
RSpec/LetSetup:
|
292
345
|
Description: Checks unreferenced `let!` calls being used for test setup.
|
293
346
|
Enabled: true
|
347
|
+
VersionAdded: '1.7'
|
294
348
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LetSetup
|
295
349
|
|
296
350
|
RSpec/MessageChain:
|
297
351
|
Description: Check that chains of messages are not being stubbed.
|
298
352
|
Enabled: true
|
353
|
+
VersionAdded: '1.7'
|
299
354
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MessageChain
|
300
355
|
|
301
356
|
RSpec/MessageExpectation:
|
@@ -305,6 +360,8 @@ RSpec/MessageExpectation:
|
|
305
360
|
SupportedStyles:
|
306
361
|
- allow
|
307
362
|
- expect
|
363
|
+
VersionAdded: '1.7'
|
364
|
+
VersionChanged: '1.8'
|
308
365
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MessageExpectation
|
309
366
|
|
310
367
|
RSpec/MessageSpies:
|
@@ -314,58 +371,70 @@ RSpec/MessageSpies:
|
|
314
371
|
SupportedStyles:
|
315
372
|
- have_received
|
316
373
|
- receive
|
374
|
+
VersionAdded: '1.9'
|
317
375
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MessageSpies
|
318
376
|
|
319
377
|
RSpec/MissingExampleGroupArgument:
|
320
378
|
Description: Checks that the first argument to an example group is not empty.
|
321
379
|
Enabled: true
|
380
|
+
VersionAdded: '1.28'
|
322
381
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MissingExampleGroupArgument
|
323
382
|
|
324
383
|
RSpec/MultipleDescribes:
|
325
384
|
Description: Checks for multiple top level describes.
|
326
385
|
Enabled: true
|
386
|
+
VersionAdded: '1.0'
|
327
387
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleDescribes
|
328
388
|
|
329
389
|
RSpec/MultipleExpectations:
|
330
390
|
Description: Checks if examples contain too many `expect` calls.
|
331
391
|
Enabled: true
|
332
392
|
Max: 1
|
393
|
+
VersionAdded: '1.7'
|
394
|
+
VersionChanged: '1.21'
|
333
395
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleExpectations
|
334
396
|
|
335
397
|
RSpec/MultipleSubjects:
|
336
398
|
Description: Checks if an example group defines `subject` multiple times.
|
337
399
|
Enabled: true
|
400
|
+
VersionAdded: '1.16'
|
338
401
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleSubjects
|
339
402
|
|
340
403
|
RSpec/NamedSubject:
|
341
404
|
Description: Checks for explicitly referenced test subjects.
|
342
405
|
Enabled: true
|
343
406
|
IgnoreSharedExamples: true
|
407
|
+
VersionAdded: 1.5.3
|
344
408
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NamedSubject
|
345
409
|
|
346
410
|
RSpec/NestedGroups:
|
347
411
|
Description: Checks for nested example groups.
|
348
412
|
Enabled: true
|
349
413
|
Max: 3
|
414
|
+
VersionAdded: '1.7'
|
415
|
+
VersionChanged: '1.10'
|
350
416
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NestedGroups
|
351
417
|
|
352
418
|
RSpec/NotToNot:
|
353
419
|
Description: Checks for consistent method usage for negating expectations.
|
420
|
+
Enabled: true
|
354
421
|
EnforcedStyle: not_to
|
355
422
|
SupportedStyles:
|
356
423
|
- not_to
|
357
424
|
- to_not
|
358
|
-
|
425
|
+
VersionAdded: '1.4'
|
359
426
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NotToNot
|
360
427
|
|
361
428
|
RSpec/OverwritingSetup:
|
362
|
-
Enabled: true
|
363
429
|
Description: Checks if there is a let/subject that overwrites an existing one.
|
430
|
+
Enabled: true
|
431
|
+
VersionAdded: '1.14'
|
364
432
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/OverwritingSetup
|
365
433
|
|
366
434
|
RSpec/Pending:
|
367
|
-
Enabled: false
|
368
435
|
Description: Checks for any pending or skipped examples.
|
436
|
+
Enabled: false
|
437
|
+
VersionAdded: '1.25'
|
369
438
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Pending
|
370
439
|
|
371
440
|
RSpec/PredicateMatcher:
|
@@ -377,109 +446,154 @@ RSpec/PredicateMatcher:
|
|
377
446
|
SupportedStyles:
|
378
447
|
- inflected
|
379
448
|
- explicit
|
449
|
+
SafeAutoCorrect: false
|
450
|
+
VersionAdded: '1.16'
|
380
451
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/PredicateMatcher
|
381
452
|
|
382
453
|
RSpec/ReceiveCounts:
|
383
|
-
Enabled: true
|
384
454
|
Description: Check for `once` and `twice` receive counts matchers usage.
|
455
|
+
Enabled: true
|
456
|
+
VersionAdded: '1.26'
|
385
457
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReceiveCounts
|
386
458
|
|
387
459
|
RSpec/ReceiveNever:
|
388
|
-
Enabled: true
|
389
460
|
Description: Prefer `not_to receive(...)` over `receive(...).never`.
|
461
|
+
Enabled: true
|
462
|
+
VersionAdded: '1.28'
|
390
463
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReceiveNever
|
391
464
|
|
392
465
|
RSpec/RepeatedDescription:
|
393
|
-
Enabled: true
|
394
466
|
Description: Check for repeated description strings in example groups.
|
467
|
+
Enabled: true
|
468
|
+
VersionAdded: '1.9'
|
395
469
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedDescription
|
396
470
|
|
397
471
|
RSpec/RepeatedExample:
|
398
|
-
Enabled: true
|
399
472
|
Description: Check for repeated examples within example groups.
|
473
|
+
Enabled: true
|
474
|
+
VersionAdded: '1.10'
|
400
475
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedExample
|
401
476
|
|
402
477
|
RSpec/RepeatedExampleGroupBody:
|
403
|
-
Enabled: true
|
404
478
|
Description: Check for repeated describe and context block body.
|
479
|
+
Enabled: true
|
480
|
+
VersionAdded: '1.38'
|
405
481
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedExampleGroupBody
|
406
482
|
|
407
483
|
RSpec/RepeatedExampleGroupDescription:
|
408
|
-
Enabled: true
|
409
484
|
Description: Check for repeated example group descriptions.
|
485
|
+
Enabled: true
|
486
|
+
VersionAdded: '1.38'
|
410
487
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedExampleGroupDescription
|
411
488
|
|
412
489
|
RSpec/ReturnFromStub:
|
413
|
-
Enabled: true
|
414
490
|
Description: Checks for consistent style of stub's return setting.
|
491
|
+
Enabled: true
|
415
492
|
EnforcedStyle: and_return
|
416
493
|
SupportedStyles:
|
417
494
|
- and_return
|
418
495
|
- block
|
496
|
+
VersionAdded: '1.16'
|
497
|
+
VersionChanged: '1.22'
|
419
498
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReturnFromStub
|
420
499
|
|
421
500
|
RSpec/ScatteredLet:
|
422
501
|
Description: Checks for let scattered across the example group.
|
423
502
|
Enabled: true
|
424
|
-
|
503
|
+
VersionAdded: '1.14'
|
425
504
|
VersionChanged: '1.39'
|
505
|
+
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredLet
|
426
506
|
|
427
507
|
RSpec/ScatteredSetup:
|
428
508
|
Description: Checks for setup scattered across multiple hooks in an example group.
|
429
509
|
Enabled: true
|
510
|
+
VersionAdded: '1.10'
|
430
511
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredSetup
|
431
512
|
|
432
513
|
RSpec/SharedContext:
|
433
514
|
Description: Checks for proper shared_context and shared_examples usage.
|
434
515
|
Enabled: true
|
516
|
+
VersionAdded: '1.13'
|
435
517
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SharedContext
|
436
518
|
|
437
519
|
RSpec/SharedExamples:
|
438
520
|
Description: Enforces use of string to titleize shared examples.
|
439
521
|
Enabled: true
|
522
|
+
VersionAdded: '1.25'
|
440
523
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SharedExamples
|
441
524
|
|
442
525
|
RSpec/SingleArgumentMessageChain:
|
443
526
|
Description: Checks that chains of messages contain more than one element.
|
444
527
|
Enabled: true
|
528
|
+
VersionAdded: '1.9'
|
529
|
+
VersionChanged: '1.10'
|
445
530
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SingleArgumentMessageChain
|
446
531
|
|
447
532
|
RSpec/SubjectStub:
|
448
533
|
Description: Checks for stubbed test subjects.
|
449
534
|
Enabled: true
|
535
|
+
VersionAdded: '1.7'
|
450
536
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SubjectStub
|
451
537
|
|
452
538
|
RSpec/UnspecifiedException:
|
453
539
|
Description: Checks for a specified error in checking raised errors.
|
454
540
|
Enabled: true
|
541
|
+
VersionAdded: '1.30'
|
455
542
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/UnspecifiedException
|
456
543
|
|
544
|
+
RSpec/VariableDefinition:
|
545
|
+
Description: Checks that memoized helpers names are symbols or strings.
|
546
|
+
Enabled: true
|
547
|
+
EnforcedStyle: symbols
|
548
|
+
SupportedStyles:
|
549
|
+
- symbols
|
550
|
+
- strings
|
551
|
+
VersionAdded: '1.40'
|
552
|
+
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VariableDefinition
|
553
|
+
|
554
|
+
RSpec/VariableName:
|
555
|
+
Description: Checks that memoized helper names use the configured style.
|
556
|
+
Enabled: true
|
557
|
+
EnforcedStyle: snake_case
|
558
|
+
SupportedStyles:
|
559
|
+
- snake_case
|
560
|
+
- camelCase
|
561
|
+
VersionAdded: '1.40'
|
562
|
+
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VariableName
|
563
|
+
|
457
564
|
RSpec/VerifiedDoubles:
|
458
565
|
Description: Prefer using verifying doubles over normal doubles.
|
459
566
|
Enabled: true
|
460
567
|
IgnoreNameless: true
|
461
568
|
IgnoreSymbolicNames: false
|
569
|
+
VersionAdded: 1.2.1
|
570
|
+
VersionChanged: '1.5'
|
462
571
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubles
|
463
572
|
|
464
573
|
RSpec/VoidExpect:
|
465
574
|
Description: This cop checks void `expect()`.
|
466
575
|
Enabled: true
|
576
|
+
VersionAdded: '1.16'
|
467
577
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect
|
468
578
|
|
469
579
|
RSpec/Yield:
|
470
580
|
Description: This cop checks for calling a block within a stub.
|
471
581
|
Enabled: true
|
582
|
+
VersionAdded: '1.32'
|
472
583
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Yield
|
473
584
|
|
474
585
|
Capybara/CurrentPathExpectation:
|
475
586
|
Description: Checks that no expectations are set on Capybara's `current_path`.
|
476
587
|
Enabled: true
|
588
|
+
VersionAdded: '1.18'
|
477
589
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/CurrentPathExpectation
|
478
590
|
|
479
591
|
Capybara/FeatureMethods:
|
480
592
|
Description: Checks for consistent method usage in feature specs.
|
481
593
|
Enabled: true
|
482
594
|
EnabledMethods: []
|
595
|
+
VersionAdded: '1.17'
|
596
|
+
VersionChanged: '1.25'
|
483
597
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Capybara/FeatureMethods
|
484
598
|
|
485
599
|
Capybara/VisibilityMatcher:
|
@@ -491,6 +605,7 @@ Capybara/VisibilityMatcher:
|
|
491
605
|
FactoryBot/AttributeDefinedStatically:
|
492
606
|
Description: Always declare attribute values as blocks.
|
493
607
|
Enabled: true
|
608
|
+
VersionAdded: '1.28'
|
494
609
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/AttributeDefinedStatically
|
495
610
|
|
496
611
|
FactoryBot/CreateList:
|
@@ -500,11 +615,13 @@ FactoryBot/CreateList:
|
|
500
615
|
SupportedStyles:
|
501
616
|
- create_list
|
502
617
|
- n_times
|
618
|
+
VersionAdded: '1.25'
|
503
619
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/CreateList
|
504
620
|
|
505
621
|
FactoryBot/FactoryClassName:
|
506
622
|
Description: Use string value when setting the class attribute explicitly.
|
507
623
|
Enabled: true
|
624
|
+
VersionAdded: '1.37'
|
508
625
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/FactoryClassName
|
509
626
|
|
510
627
|
Rails/HttpStatus:
|
@@ -514,4 +631,5 @@ Rails/HttpStatus:
|
|
514
631
|
SupportedStyles:
|
515
632
|
- numeric
|
516
633
|
- symbolic
|
634
|
+
VersionAdded: '1.23'
|
517
635
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HttpStatus
|
data/lib/rubocop-rspec.rb
CHANGED
@@ -17,6 +17,7 @@ require_relative 'rubocop/rspec/concept'
|
|
17
17
|
require_relative 'rubocop/rspec/example_group'
|
18
18
|
require_relative 'rubocop/rspec/example'
|
19
19
|
require_relative 'rubocop/rspec/hook'
|
20
|
+
require_relative 'rubocop/rspec/variable'
|
20
21
|
require_relative 'rubocop/cop/rspec/cop'
|
21
22
|
require_relative 'rubocop/rspec/align_let_brace'
|
22
23
|
require_relative 'rubocop/rspec/factory_bot'
|
@@ -18,35 +18,50 @@ module RuboCop
|
|
18
18
|
#
|
19
19
|
# # bad
|
20
20
|
# expect(page).to have_selector('.foo', visible: false)
|
21
|
-
#
|
22
|
-
#
|
23
|
-
# expect(page).to have_selector('.foo', visible: true)
|
24
|
-
#
|
25
|
-
# # good
|
26
|
-
# expect(page).to have_selector('.foo', visible: :all)
|
27
|
-
#
|
28
|
-
# # good
|
29
|
-
# expect(page).to have_selector('.foo', visible: :hidden)
|
21
|
+
# expect(page).to have_css('.foo', visible: true)
|
22
|
+
# expect(page).to have_link('my link', visible: false)
|
30
23
|
#
|
31
24
|
# # good
|
32
25
|
# expect(page).to have_selector('.foo', visible: :visible)
|
26
|
+
# expect(page).to have_css('.foo', visible: :all)
|
27
|
+
# expect(page).to have_link('my link', visible: :hidden)
|
33
28
|
#
|
34
29
|
class VisibilityMatcher < Cop
|
35
30
|
MSG_FALSE = 'Use `:all` or `:hidden` instead of `false`.'
|
36
31
|
MSG_TRUE = 'Use `:visible` instead of `true`.'
|
32
|
+
CAPYBARA_MATCHER_METHODS = %i[
|
33
|
+
have_selector
|
34
|
+
have_css
|
35
|
+
have_xpath
|
36
|
+
have_link
|
37
|
+
have_button
|
38
|
+
have_field
|
39
|
+
have_select
|
40
|
+
have_table
|
41
|
+
have_checked_field
|
42
|
+
have_unchecked_field
|
43
|
+
have_text
|
44
|
+
have_content
|
45
|
+
].freeze
|
37
46
|
|
38
47
|
def_node_matcher :visible_true?, <<~PATTERN
|
39
|
-
(send nil?
|
48
|
+
(send nil? #capybara_matcher? ... (hash <$(pair (sym :visible) true) ...>))
|
40
49
|
PATTERN
|
41
50
|
|
42
51
|
def_node_matcher :visible_false?, <<~PATTERN
|
43
|
-
(send nil?
|
52
|
+
(send nil? #capybara_matcher? ... (hash <$(pair (sym :visible) false) ...>))
|
44
53
|
PATTERN
|
45
54
|
|
46
55
|
def on_send(node)
|
47
56
|
visible_false?(node) { |arg| add_offense(arg, message: MSG_FALSE) }
|
48
57
|
visible_true?(node) { |arg| add_offense(arg, message: MSG_TRUE) }
|
49
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def capybara_matcher?(method_name)
|
63
|
+
CAPYBARA_MATCHER_METHODS.include? method_name
|
64
|
+
end
|
50
65
|
end
|
51
66
|
end
|
52
67
|
end
|
@@ -2,28 +2,8 @@
|
|
2
2
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
|
-
WorkaroundCop = Cop.dup
|
6
|
-
|
7
|
-
# Clone of the the normal RuboCop::Cop::Cop class so we can rewrite
|
8
|
-
# the inherited method without breaking functionality
|
9
|
-
class WorkaroundCop
|
10
|
-
# Remove the Cop.inherited method to be a noop. Our RSpec::Cop
|
11
|
-
# class will invoke the inherited hook instead
|
12
|
-
class << self
|
13
|
-
undef inherited
|
14
|
-
def inherited(*) end
|
15
|
-
end
|
16
|
-
|
17
|
-
# Special case `Module#<` so that the rspec support rubocop exports
|
18
|
-
# is compatible with our subclass
|
19
|
-
def self.<(other)
|
20
|
-
other.equal?(RuboCop::Cop::Cop) || super
|
21
|
-
end
|
22
|
-
end
|
23
|
-
private_constant(:WorkaroundCop)
|
24
|
-
|
25
5
|
module RSpec
|
26
|
-
# @abstract parent class to
|
6
|
+
# @abstract parent class to RSpec cops
|
27
7
|
#
|
28
8
|
# The criteria for whether rubocop-rspec analyzes a certain ruby file
|
29
9
|
# is configured via `AllCops/RSpec`. For example, if you want to
|
@@ -31,13 +11,13 @@ module RuboCop
|
|
31
11
|
# then you could add this to your configuration:
|
32
12
|
#
|
33
13
|
# @example configuring analyzed paths
|
34
|
-
#
|
35
|
-
# AllCops:
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
class Cop <
|
14
|
+
# # .rubocop.yml
|
15
|
+
# # AllCops:
|
16
|
+
# # RSpec:
|
17
|
+
# # Patterns:
|
18
|
+
# # - '_test.rb$'
|
19
|
+
# # - '(?:^|/)test/'
|
20
|
+
class Cop < ::RuboCop::Cop::Cop
|
41
21
|
include RuboCop::RSpec::Language
|
42
22
|
include RuboCop::RSpec::Language::NodePattern
|
43
23
|
|
@@ -3,10 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module RSpec
|
6
|
-
# Checks that spec file paths are consistent
|
6
|
+
# Checks that spec file paths are consistent and well-formed.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# By default, this checks that spec file paths are consistent with the
|
9
|
+
# test subject and and enforces that it reflects the described
|
10
|
+
# class/module and its optionally called out method.
|
10
11
|
#
|
11
12
|
# With the configuration option `IgnoreMethods` the called out method will
|
12
13
|
# be ignored when determining the enforced path.
|
@@ -15,6 +16,10 @@ module RuboCop
|
|
15
16
|
# be specified that should not as usual be transformed from CamelCase to
|
16
17
|
# snake_case (e.g. 'RuboCop' => 'rubocop' ).
|
17
18
|
#
|
19
|
+
# With the configuration option `SpecSuffixOnly` test files will only
|
20
|
+
# be checked to ensure they end in '_spec.rb'. This option disables
|
21
|
+
# checking for consistency in the test subject or test methods.
|
22
|
+
#
|
18
23
|
# @example
|
19
24
|
# # bad
|
20
25
|
# whatever_spec.rb # describe MyClass
|
@@ -41,6 +46,16 @@ module RuboCop
|
|
41
46
|
# # good
|
42
47
|
# my_class_spec.rb # describe MyClass, '#method'
|
43
48
|
#
|
49
|
+
# @example when configuration is `SpecSuffixOnly: true`
|
50
|
+
# # good
|
51
|
+
# whatever_spec.rb # describe MyClass
|
52
|
+
#
|
53
|
+
# # good
|
54
|
+
# my_class_spec.rb # describe MyClass
|
55
|
+
#
|
56
|
+
# # good
|
57
|
+
# my_class_spec.rb # describe MyClass, '#method'
|
58
|
+
#
|
44
59
|
class FilePath < Cop
|
45
60
|
include RuboCop::RSpec::TopLevelDescribe
|
46
61
|
|
@@ -70,9 +85,15 @@ module RuboCop
|
|
70
85
|
end
|
71
86
|
|
72
87
|
def glob_for((described_class, method_name))
|
88
|
+
return glob_for_spec_suffix_only? if spec_suffix_only?
|
89
|
+
|
73
90
|
"#{expected_path(described_class)}#{name_glob(method_name)}*_spec.rb"
|
74
91
|
end
|
75
92
|
|
93
|
+
def glob_for_spec_suffix_only?
|
94
|
+
'*_spec.rb'
|
95
|
+
end
|
96
|
+
|
76
97
|
def name_glob(name)
|
77
98
|
return unless name&.str_type?
|
78
99
|
|
@@ -105,12 +126,17 @@ module RuboCop
|
|
105
126
|
def filename_ends_with?(glob)
|
106
127
|
filename =
|
107
128
|
RuboCop::PathUtil.relative_path(processed_source.buffer.name)
|
129
|
+
.gsub('../', '')
|
108
130
|
File.fnmatch?("*#{glob}", filename)
|
109
131
|
end
|
110
132
|
|
111
133
|
def relevant_rubocop_rspec_file?(_file)
|
112
134
|
true
|
113
135
|
end
|
136
|
+
|
137
|
+
def spec_suffix_only?
|
138
|
+
cop_config['SpecSuffixOnly']
|
139
|
+
end
|
114
140
|
end
|
115
141
|
end
|
116
142
|
end
|
@@ -70,6 +70,7 @@ module RuboCop
|
|
70
70
|
'to describe HTTP status code.'
|
71
71
|
|
72
72
|
attr_reader :node
|
73
|
+
|
73
74
|
def initialize(node)
|
74
75
|
@node = node
|
75
76
|
end
|
@@ -110,6 +111,7 @@ module RuboCop
|
|
110
111
|
ALLOWED_STATUSES = %i[error success missing redirect].freeze
|
111
112
|
|
112
113
|
attr_reader :node
|
114
|
+
|
113
115
|
def initialize(node)
|
114
116
|
@node = node
|
115
117
|
end
|
@@ -34,6 +34,15 @@ module RuboCop
|
|
34
34
|
# it { cool_predicate }
|
35
35
|
# end
|
36
36
|
#
|
37
|
+
# # good
|
38
|
+
# context Array do
|
39
|
+
# it { is_expected.to respond_to :each }
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# context Hash do
|
43
|
+
# it { is_expected.to respond_to :each }
|
44
|
+
# end
|
45
|
+
#
|
37
46
|
class RepeatedExampleGroupBody < Cop
|
38
47
|
MSG = 'Repeated %<group>s block body on line(s) %<loc>s'
|
39
48
|
|
@@ -43,6 +52,7 @@ module RuboCop
|
|
43
52
|
|
44
53
|
def_node_matcher :metadata, '(block (send _ _ _ $...) ...)'
|
45
54
|
def_node_matcher :body, '(block _ args $...)'
|
55
|
+
def_node_matcher :const_arg, '(block (send _ _ $const ...) ...)'
|
46
56
|
|
47
57
|
def_node_matcher :skip_or_pending?, <<-PATTERN
|
48
58
|
(block <(send nil? {:skip :pending}) ...>)
|
@@ -75,7 +85,7 @@ module RuboCop
|
|
75
85
|
end
|
76
86
|
|
77
87
|
def signature_keys(group)
|
78
|
-
[metadata(group), body(group)]
|
88
|
+
[metadata(group), body(group), const_arg(group)]
|
79
89
|
end
|
80
90
|
|
81
91
|
def message(group, repeats)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
module RuboCop
|
4
6
|
module Cop
|
5
7
|
module RSpec
|
@@ -75,70 +77,46 @@ module RuboCop
|
|
75
77
|
|
76
78
|
def on_block(node)
|
77
79
|
return unless example_group?(node)
|
80
|
+
return if (processed_example_groups & node.ancestors).any?
|
81
|
+
|
82
|
+
processed_example_groups << node
|
83
|
+
@explicit_subjects = find_all_explicit_subjects(node)
|
78
84
|
|
79
|
-
|
85
|
+
find_subject_expectations(node) do |stub|
|
80
86
|
add_offense(stub)
|
81
87
|
end
|
82
88
|
end
|
83
89
|
|
84
90
|
private
|
85
91
|
|
86
|
-
|
87
|
-
|
88
|
-
# @param node [RuboCop::Node] example group
|
89
|
-
#
|
90
|
-
# @yield [RuboCop::Node] message expectations for subject
|
91
|
-
def find_subject_stub(node, &block)
|
92
|
-
find_subject(node) do |subject_name, context|
|
93
|
-
find_subject_expectation(context, subject_name, &block)
|
94
|
-
end
|
92
|
+
def processed_example_groups
|
93
|
+
@processed_example_groups ||= Set.new
|
95
94
|
end
|
96
95
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
#
|
102
|
-
# @yield [RuboCop::Node] message expectation
|
103
|
-
def find_subject_expectation(node, subject_name, &block)
|
104
|
-
# Do not search node if it is an example group with its own subject.
|
105
|
-
return if example_group?(node) && redefines_subject?(node)
|
106
|
-
|
107
|
-
# Yield the current node if it is a message expectation.
|
108
|
-
yield(node) if message_expectation?(node, subject_name)
|
96
|
+
def find_all_explicit_subjects(node)
|
97
|
+
node.each_descendant(:block).with_object({}) do |child, h|
|
98
|
+
name = subject(child)
|
99
|
+
next unless name
|
109
100
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
end
|
114
|
-
end
|
101
|
+
outer_example_group = child.each_ancestor.find do |a|
|
102
|
+
example_group?(a)
|
103
|
+
end
|
115
104
|
|
116
|
-
|
117
|
-
|
118
|
-
# @param node [RuboCop::Node]
|
119
|
-
#
|
120
|
-
# @return [Boolean]
|
121
|
-
def redefines_subject?(node)
|
122
|
-
node.each_child_node.any? do |child|
|
123
|
-
subject(child) || redefines_subject?(child)
|
105
|
+
h[outer_example_group] ||= []
|
106
|
+
h[outer_example_group] << name
|
124
107
|
end
|
125
108
|
end
|
126
109
|
|
127
|
-
|
128
|
-
|
129
|
-
# @param node [RuboCop::Node]
|
130
|
-
# @param parent [RuboCop::Node,nil]
|
131
|
-
#
|
132
|
-
# @yieldparam subject_name [Symbol] name of subject being defined
|
133
|
-
# @yieldparam parent [RuboCop::Node] parent of subject definition
|
134
|
-
def find_subject(node, parent: nil, &block)
|
135
|
-
# An implicit subject is defined by RSpec when no subject is declared
|
136
|
-
subject_name = subject(node) || :subject
|
110
|
+
def find_subject_expectations(node, subject_names = [], &block)
|
111
|
+
subject_names = @explicit_subjects[node] if @explicit_subjects[node]
|
137
112
|
|
138
|
-
|
113
|
+
expectation_detected = (subject_names + [:subject]).any? do |name|
|
114
|
+
message_expectation?(node, name)
|
115
|
+
end
|
116
|
+
return yield(node) if expectation_detected
|
139
117
|
|
140
118
|
node.each_child_node do |child|
|
141
|
-
|
119
|
+
find_subject_expectations(child, subject_names, &block)
|
142
120
|
end
|
143
121
|
end
|
144
122
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks that memoized helpers names are symbols or strings.
|
7
|
+
#
|
8
|
+
# @example EnforcedStyle: symbols (default)
|
9
|
+
# # bad
|
10
|
+
# let('user_name') { 'Adam' }
|
11
|
+
# subject('user') { create_user }
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# let(:user_name) { 'Adam' }
|
15
|
+
# subject(:user) { create_user }
|
16
|
+
#
|
17
|
+
# @example EnforcedStyle: strings
|
18
|
+
# # bad
|
19
|
+
# let(:user_name) { 'Adam' }
|
20
|
+
# subject(:user) { create_user }
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# let('user_name') { 'Adam' }
|
24
|
+
# subject('user') { create_user }
|
25
|
+
class VariableDefinition < Cop
|
26
|
+
include ConfigurableEnforcedStyle
|
27
|
+
include RuboCop::RSpec::Variable
|
28
|
+
|
29
|
+
MSG = 'Use %<style>s for variable names.'
|
30
|
+
|
31
|
+
def on_send(node)
|
32
|
+
variable_definition?(node) do |variable|
|
33
|
+
if style_violation?(variable)
|
34
|
+
add_offense(variable, message: format(MSG, style: style))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def style_violation?(variable)
|
42
|
+
style == :symbols && string?(variable) ||
|
43
|
+
style == :strings && symbol?(variable)
|
44
|
+
end
|
45
|
+
|
46
|
+
def string?(node)
|
47
|
+
node.str_type? || node.dstr_type?
|
48
|
+
end
|
49
|
+
|
50
|
+
def symbol?(node)
|
51
|
+
node.sym_type? || node.dsym_type?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks that memoized helper names use the configured style.
|
7
|
+
#
|
8
|
+
# @example EnforcedStyle: snake_case (default)
|
9
|
+
# # bad
|
10
|
+
# let(:userName) { 'Adam' }
|
11
|
+
# subject(:userName) { 'Adam' }
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# let(:user_name) { 'Adam' }
|
15
|
+
# subject(:user_name) { 'Adam' }
|
16
|
+
#
|
17
|
+
# @example EnforcedStyle: camelCase
|
18
|
+
# # bad
|
19
|
+
# let(:user_name) { 'Adam' }
|
20
|
+
# subject(:user_name) { 'Adam' }
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# let(:userName) { 'Adam' }
|
24
|
+
# subject(:userName) { 'Adam' }
|
25
|
+
class VariableName < Cop
|
26
|
+
include ConfigurableNaming
|
27
|
+
include RuboCop::RSpec::Variable
|
28
|
+
|
29
|
+
MSG = 'Use %<style>s for variable names.'
|
30
|
+
|
31
|
+
def on_send(node)
|
32
|
+
variable_definition?(node) do |variable|
|
33
|
+
return if variable.dstr_type? || variable.dsym_type?
|
34
|
+
|
35
|
+
check_name(node, variable.value, variable.loc.expression)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def message(style)
|
42
|
+
format(MSG, style: style)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -86,6 +86,8 @@ require_relative 'rspec/shared_examples'
|
|
86
86
|
require_relative 'rspec/single_argument_message_chain'
|
87
87
|
require_relative 'rspec/subject_stub'
|
88
88
|
require_relative 'rspec/unspecified_exception'
|
89
|
+
require_relative 'rspec/variable_definition'
|
90
|
+
require_relative 'rspec/variable_name'
|
89
91
|
require_relative 'rspec/verified_doubles'
|
90
92
|
require_relative 'rspec/void_expect'
|
91
93
|
require_relative 'rspec/yield'
|
@@ -21,7 +21,7 @@ module RuboCop
|
|
21
21
|
|
22
22
|
# Decorator of a YARD code object for working with documented rspec cops
|
23
23
|
class CodeObject
|
24
|
-
|
24
|
+
COP_CLASS_NAME = 'RuboCop::Cop::RSpec::Cop'
|
25
25
|
RSPEC_NAMESPACE = 'RuboCop::Cop::RSpec'
|
26
26
|
|
27
27
|
def initialize(yardoc)
|
@@ -68,11 +68,7 @@ module RuboCop
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def cop_subclass?
|
71
|
-
|
72
|
-
# RuboCop::Cop::WorkaroundCop are shown as having RuboCop::Cop as
|
73
|
-
# superclass, while all the following classes are listed as having
|
74
|
-
# RuboCop::Cop::RSpec::Cop as their superclass.
|
75
|
-
COP_CLASS_NAMES.include?(yardoc.superclass.path)
|
71
|
+
yardoc.superclass.path == COP_CLASS_NAME
|
76
72
|
end
|
77
73
|
|
78
74
|
def abstract?
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module RSpec
|
5
|
+
# Helps check offenses with variable definitions
|
6
|
+
module Variable
|
7
|
+
include Language
|
8
|
+
extend RuboCop::NodePattern::Macros
|
9
|
+
|
10
|
+
def_node_matcher :variable_definition?, <<~PATTERN
|
11
|
+
(send #{RSPEC} #{(Helpers::ALL + Subject::ALL).node_pattern_union}
|
12
|
+
$({sym str dsym dstr} ...) ...)
|
13
|
+
PATTERN
|
14
|
+
end
|
15
|
+
end
|
16
|
+
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: 1.
|
4
|
+
version: 1.40.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: 2020-
|
13
|
+
date: 2020-06-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -194,6 +194,8 @@ files:
|
|
194
194
|
- lib/rubocop/cop/rspec/single_argument_message_chain.rb
|
195
195
|
- lib/rubocop/cop/rspec/subject_stub.rb
|
196
196
|
- lib/rubocop/cop/rspec/unspecified_exception.rb
|
197
|
+
- lib/rubocop/cop/rspec/variable_definition.rb
|
198
|
+
- lib/rubocop/cop/rspec/variable_name.rb
|
197
199
|
- lib/rubocop/cop/rspec/verified_doubles.rb
|
198
200
|
- lib/rubocop/cop/rspec/void_expect.rb
|
199
201
|
- lib/rubocop/cop/rspec/yield.rb
|
@@ -215,6 +217,7 @@ files:
|
|
215
217
|
- lib/rubocop/rspec/language/node_pattern.rb
|
216
218
|
- lib/rubocop/rspec/node.rb
|
217
219
|
- lib/rubocop/rspec/top_level_describe.rb
|
220
|
+
- lib/rubocop/rspec/variable.rb
|
218
221
|
- lib/rubocop/rspec/version.rb
|
219
222
|
- lib/rubocop/rspec/wording.rb
|
220
223
|
homepage: https://github.com/rubocop-hq/rubocop-rspec
|