rubocop-rspec 1.29.1 → 1.30.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/config/default.yml +48 -41
- data/lib/rubocop-rspec.rb +0 -2
- data/lib/rubocop/cop/rspec/context_wording.rb +1 -0
- data/lib/rubocop/cop/rspec/cop.rb +1 -0
- data/lib/rubocop/cop/rspec/describe_method.rb +1 -3
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +2 -1
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +1 -0
- data/lib/rubocop/cop/rspec/implicit_subject.rb +13 -2
- data/lib/rubocop/cop/rspec/let_before_examples.rb +1 -0
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -0
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +2 -0
- data/lib/rubocop/cop/rspec/rails/http_status.rb +1 -0
- data/lib/rubocop/cop/rspec/scattered_let.rb +1 -0
- data/lib/rubocop/cop/rspec/subject_stub.rb +1 -0
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +64 -0
- data/lib/rubocop/cop/rspec/verified_doubles.rb +10 -3
- data/lib/rubocop/cop/rspec/void_expect.rb +3 -0
- data/lib/rubocop/cop/rspec_cops.rb +1 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- data/spec/project/default_config_spec.rb +16 -3
- data/spec/rubocop/cop/rspec/factory_bot/attribute_defined_statically_spec.rb +2 -0
- data/spec/rubocop/cop/rspec/implicit_subject_spec.rb +58 -0
- data/spec/rubocop/cop/rspec/unspecified_exception_spec.rb +175 -0
- data/spec/rubocop/cop/rspec/verified_doubles_spec.rb +15 -2
- metadata +5 -4
- data/lib/rubocop/rspec/capybara.rb +0 -7
- data/lib/rubocop/rspec/factory_bot.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a59e8fa42b2cb3434cc923508e5fb7fb23959eea5912588425575216966173c
|
4
|
+
data.tar.gz: e0a0419763273fba02709cd92c1c86c6704398e24947d29d9499df29cf60efec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bc9fa634cc51edc446f4ea65f8590fedafbcb754b5667383aa3f0b71cc5a8aaff114f40d093d261a43b642efdb23f8ac2a39047fab2b9104c768362ab0c2569
|
7
|
+
data.tar.gz: b5c52f755b673b2f0fd1a3075a1b1a61060f4216f2b1548a24e4622da5a93f9ada94c39d4abc9644d92bae22cd5019c89693a3d1d6cd32952c748dbfdf8b554f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
## Master (Unreleased)
|
4
4
|
|
5
|
+
## 1.30.0 (2018-10-08)
|
6
|
+
|
7
|
+
* Add config to `RSpec/VerifiedDoubles` to enforcement of verification on unnamed doubles. ([@BrentWheeldon][])
|
8
|
+
* Fix `FactoryBot/AttributeDefinedStatically` not working when there is a non-symbol key. ([@vzvu3k6k][])
|
9
|
+
* Fix false positive in `RSpec/ImplicitSubject` when `is_expected` is used inside `its()` block. ([@Darhazer][])
|
10
|
+
* Add `single_statement_only` style to `RSpec/ImplicitSubject` as a more relaxed alternative to `single_line_only`. ([@Darhazer][])
|
11
|
+
* Add `RSpec/UnspecifiedException` as a default cop to encourage more-specific `expect{}.to raise_error(ExceptionType)`, or `raise_exception` style handling of exceptions. ([@daveworth][])
|
12
|
+
|
5
13
|
## 1.29.1 (2018-09-01)
|
6
14
|
|
7
15
|
* Fix false negative in `FactoryBot/AttributeDefinedStatically` when attribute is defined on `self`. ([@Darhazer][])
|
@@ -374,3 +382,6 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
|
|
374
382
|
[@tdeo]: https://github.com/tdeo
|
375
383
|
[@composerinteralia]: https://github.com/composerinteralia
|
376
384
|
[@seanpdoyle]: https://github.com/seanpdoyle
|
385
|
+
[@vzvu3k6k]: https://github.com/vzvu3k6k
|
386
|
+
[@BrentWheeldon]: https://github.com/BrentWheeldon
|
387
|
+
[@daveworth]: https://github.com/daveworth
|
data/config/default.yml
CHANGED
@@ -10,16 +10,6 @@ AllCops:
|
|
10
10
|
- spec/factories/**/*.rb
|
11
11
|
- features/support/factories/**/*.rb
|
12
12
|
|
13
|
-
RSpec/AnyInstance:
|
14
|
-
Description: Check that instances are not being stubbed globally.
|
15
|
-
Enabled: true
|
16
|
-
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AnyInstance
|
17
|
-
|
18
|
-
RSpec/AroundBlock:
|
19
|
-
Description: Checks that around blocks actually run the test.
|
20
|
-
Enabled: true
|
21
|
-
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AroundBlock
|
22
|
-
|
23
13
|
RSpec/AlignLeftLetBrace:
|
24
14
|
Description: Checks that left braces for adjacent single line lets are aligned.
|
25
15
|
Enabled: false
|
@@ -30,6 +20,16 @@ RSpec/AlignRightLetBrace:
|
|
30
20
|
Enabled: false
|
31
21
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AlignRightLetBrace
|
32
22
|
|
23
|
+
RSpec/AnyInstance:
|
24
|
+
Description: Check that instances are not being stubbed globally.
|
25
|
+
Enabled: true
|
26
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AnyInstance
|
27
|
+
|
28
|
+
RSpec/AroundBlock:
|
29
|
+
Description: Checks that around blocks actually run the test.
|
30
|
+
Enabled: true
|
31
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/AroundBlock
|
32
|
+
|
33
33
|
RSpec/Be:
|
34
34
|
Description: Check for expectations where `be` is used without argument.
|
35
35
|
Enabled: true
|
@@ -63,16 +63,6 @@ RSpec/DescribeClass:
|
|
63
63
|
Enabled: true
|
64
64
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass
|
65
65
|
|
66
|
-
RSpec/DescribedClass:
|
67
|
-
Description: Checks that tests use `described_class`.
|
68
|
-
SkipBlocks: false
|
69
|
-
Enabled: true
|
70
|
-
EnforcedStyle: described_class
|
71
|
-
SupportedStyles:
|
72
|
-
- described_class
|
73
|
-
- explicit
|
74
|
-
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribedClass
|
75
|
-
|
76
66
|
RSpec/DescribeMethod:
|
77
67
|
Description: Checks that the second argument to `describe` specifies a method.
|
78
68
|
Enabled: true
|
@@ -83,10 +73,15 @@ RSpec/DescribeSymbol:
|
|
83
73
|
Enabled: true
|
84
74
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeSymbol
|
85
75
|
|
86
|
-
RSpec/
|
87
|
-
Description:
|
76
|
+
RSpec/DescribedClass:
|
77
|
+
Description: Checks that tests use `described_class`.
|
78
|
+
SkipBlocks: false
|
88
79
|
Enabled: true
|
89
|
-
|
80
|
+
EnforcedStyle: described_class
|
81
|
+
SupportedStyles:
|
82
|
+
- described_class
|
83
|
+
- explicit
|
84
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribedClass
|
90
85
|
|
91
86
|
RSpec/EmptyExampleGroup:
|
92
87
|
Description: Checks if an example group does not include any tests.
|
@@ -211,6 +206,7 @@ RSpec/ImplicitSubject:
|
|
211
206
|
EnforcedStyle: single_line_only
|
212
207
|
SupportedStyles:
|
213
208
|
- single_line_only
|
209
|
+
- single_statement_only
|
214
210
|
- disallow
|
215
211
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ImplicitSubject
|
216
212
|
|
@@ -239,6 +235,11 @@ RSpec/ItBehavesLike:
|
|
239
235
|
- it_should_behave_like
|
240
236
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ItBehavesLike
|
241
237
|
|
238
|
+
RSpec/IteratedExpectation:
|
239
|
+
Description: Check that `all` matcher is used instead of iterating over an array.
|
240
|
+
Enabled: true
|
241
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/IteratedExpectation
|
242
|
+
|
242
243
|
RSpec/LeadingSubject:
|
243
244
|
Description: Enforce that subject is the first definition in the test.
|
244
245
|
Enabled: true
|
@@ -329,6 +330,16 @@ RSpec/Pending:
|
|
329
330
|
Description: Checks for any pending or skipped examples.
|
330
331
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Pending
|
331
332
|
|
333
|
+
RSpec/PredicateMatcher:
|
334
|
+
Description: Prefer using predicate matcher over using predicate method directly.
|
335
|
+
Enabled: true
|
336
|
+
Strict: true
|
337
|
+
EnforcedStyle: inflected
|
338
|
+
SupportedStyles:
|
339
|
+
- inflected
|
340
|
+
- explicit
|
341
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/PredicateMatcher
|
342
|
+
|
332
343
|
RSpec/ReceiveCounts:
|
333
344
|
Enabled: true
|
334
345
|
Description: Check for `once` and `twice` receive counts matchers usage.
|
@@ -358,6 +369,16 @@ RSpec/ReturnFromStub:
|
|
358
369
|
- block
|
359
370
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReturnFromStub
|
360
371
|
|
372
|
+
RSpec/ScatteredLet:
|
373
|
+
Description: Checks for let scattered across the example group.
|
374
|
+
Enabled: true
|
375
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredLet
|
376
|
+
|
377
|
+
RSpec/ScatteredSetup:
|
378
|
+
Description: Checks for setup scattered across multiple hooks in an example group.
|
379
|
+
Enabled: true
|
380
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredSetup
|
381
|
+
|
361
382
|
RSpec/SharedContext:
|
362
383
|
Description: Checks for proper shared_context and shared_examples usage.
|
363
384
|
Enabled: true
|
@@ -373,34 +394,20 @@ RSpec/SingleArgumentMessageChain:
|
|
373
394
|
Enabled: true
|
374
395
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SingleArgumentMessageChain
|
375
396
|
|
376
|
-
RSpec/ScatteredLet:
|
377
|
-
Description: Checks for let scattered across the example group.
|
378
|
-
Enabled: true
|
379
|
-
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredLet
|
380
|
-
|
381
|
-
RSpec/ScatteredSetup:
|
382
|
-
Description: Checks for setup scattered across multiple hooks in an example group.
|
383
|
-
Enabled: true
|
384
|
-
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ScatteredSetup
|
385
|
-
|
386
397
|
RSpec/SubjectStub:
|
387
398
|
Description: Checks for stubbed test subjects.
|
388
399
|
Enabled: true
|
389
400
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SubjectStub
|
390
401
|
|
391
|
-
RSpec/
|
392
|
-
Description:
|
402
|
+
RSpec/UnspecifiedException:
|
403
|
+
Description: Checks for a specified error in checking raised errors.
|
393
404
|
Enabled: true
|
394
|
-
|
395
|
-
EnforcedStyle: inflected
|
396
|
-
SupportedStyles:
|
397
|
-
- inflected
|
398
|
-
- explicit
|
399
|
-
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/PredicateMatcher
|
405
|
+
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/UnspecifiedException
|
400
406
|
|
401
407
|
RSpec/VerifiedDoubles:
|
402
408
|
Description: Prefer using verifying doubles over normal doubles.
|
403
409
|
Enabled: true
|
410
|
+
IgnoreNameless: true
|
404
411
|
IgnoreSymbolicNames: false
|
405
412
|
StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubles
|
406
413
|
|
data/lib/rubocop-rspec.rb
CHANGED
@@ -18,8 +18,6 @@ require_relative 'rubocop/rspec/example'
|
|
18
18
|
require_relative 'rubocop/rspec/hook'
|
19
19
|
require_relative 'rubocop/cop/rspec/cop'
|
20
20
|
require_relative 'rubocop/rspec/align_let_brace'
|
21
|
-
require_relative 'rubocop/rspec/capybara'
|
22
|
-
require_relative 'rubocop/rspec/factory_bot'
|
23
21
|
require_relative 'rubocop/rspec/final_end_location'
|
24
22
|
require_relative 'rubocop/rspec/blank_line_separation'
|
25
23
|
|
@@ -23,11 +23,9 @@ module RuboCop
|
|
23
23
|
MSG = 'The second argument to describe should be the method '\
|
24
24
|
"being tested. '#instance' or '.class'.".freeze
|
25
25
|
|
26
|
-
METHOD_STRING_MATCHER = /\A[\#\.].+/
|
27
|
-
|
28
26
|
def on_top_level_describe(_node, (_, second_arg))
|
29
27
|
return unless second_arg && second_arg.str_type?
|
30
|
-
return if
|
28
|
+
return if second_arg.str_content.start_with?('#', '.')
|
31
29
|
|
32
30
|
add_offense(second_arg, location: :expression)
|
33
31
|
end
|
@@ -73,6 +73,7 @@ module RuboCop
|
|
73
73
|
def on_block(node)
|
74
74
|
factory_attributes(node).to_a.flatten.each do |attribute|
|
75
75
|
next if proc?(attribute) || association?(attribute)
|
76
|
+
|
76
77
|
add_offense(attribute, location: :expression)
|
77
78
|
end
|
78
79
|
end
|
@@ -97,7 +98,7 @@ module RuboCop
|
|
97
98
|
end
|
98
99
|
|
99
100
|
def factory_key?(hash_node)
|
100
|
-
hash_node.keys.any? { |key| key.value == :factory }
|
101
|
+
hash_node.keys.any? { |key| key.sym_type? && key.value == :factory }
|
101
102
|
end
|
102
103
|
|
103
104
|
def autocorrect_replacing_parens(node)
|
@@ -56,9 +56,20 @@ module RuboCop
|
|
56
56
|
private
|
57
57
|
|
58
58
|
def valid_usage?(node)
|
59
|
-
return false unless style == :single_line_only
|
60
59
|
example = node.ancestors.find { |parent| example?(parent) }
|
61
|
-
|
60
|
+
return false if example.nil?
|
61
|
+
|
62
|
+
example.method_name == :its || allowed_by_style?(example)
|
63
|
+
end
|
64
|
+
|
65
|
+
def allowed_by_style?(example)
|
66
|
+
if style == :single_line_only
|
67
|
+
example.single_line?
|
68
|
+
elsif style == :single_statement_only
|
69
|
+
!example.body.begin_type?
|
70
|
+
else
|
71
|
+
false
|
72
|
+
end
|
62
73
|
end
|
63
74
|
end
|
64
75
|
end
|
@@ -145,6 +145,7 @@ module RuboCop
|
|
145
145
|
end
|
146
146
|
|
147
147
|
return if part_of_ignored_node?(node)
|
148
|
+
|
148
149
|
predicate_matcher?(node) do |_actual, matcher|
|
149
150
|
add_offense(
|
150
151
|
node,
|
@@ -337,6 +338,7 @@ module RuboCop
|
|
337
338
|
def block_loc(send_node)
|
338
339
|
parent = send_node.parent
|
339
340
|
return unless parent.block_type?
|
341
|
+
|
340
342
|
range_between(
|
341
343
|
send_node.loc.expression.end_pos,
|
342
344
|
parent.loc.expression.end_pos
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cop
|
3
|
+
module RSpec
|
4
|
+
# Checks for a specified error in checking raised errors.
|
5
|
+
#
|
6
|
+
# Enforces one of an Exception type, a string, or a regular
|
7
|
+
# expression to match against the exception message as a parameter
|
8
|
+
# to `raise_error`
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
# expect {
|
14
|
+
# raise StandardError.new('error')
|
15
|
+
# }.to raise_error
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# expect {
|
19
|
+
# raise StandardError.new('error')
|
20
|
+
# }.to raise_error(StandardError)
|
21
|
+
#
|
22
|
+
# expect {
|
23
|
+
# raise StandardError.new('error')
|
24
|
+
# }.to raise_error('error')
|
25
|
+
#
|
26
|
+
# expect {
|
27
|
+
# raise StandardError.new('error')
|
28
|
+
# }.to raise_error(/err/)
|
29
|
+
#
|
30
|
+
# expect { do_something }.not_to raise_error
|
31
|
+
class UnspecifiedException < Cop
|
32
|
+
MSG = 'Specify the exception being captured'.freeze
|
33
|
+
|
34
|
+
def_node_matcher :empty_raise_error_or_exception, <<-PATTERN.freeze
|
35
|
+
(send
|
36
|
+
(block
|
37
|
+
(send nil? :expect) ...)
|
38
|
+
:to
|
39
|
+
(send nil? {:raise_error :raise_exception})
|
40
|
+
)
|
41
|
+
PATTERN
|
42
|
+
|
43
|
+
def on_send(node)
|
44
|
+
return unless empty_exception_matcher?(node)
|
45
|
+
|
46
|
+
add_offense(
|
47
|
+
node.children.last,
|
48
|
+
location: :expression
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def empty_exception_matcher?(node)
|
53
|
+
empty_raise_error_or_exception(node) && !block_with_args?(node.parent)
|
54
|
+
end
|
55
|
+
|
56
|
+
def block_with_args?(node)
|
57
|
+
return unless node && node.block_type?
|
58
|
+
|
59
|
+
node.arguments?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -26,16 +26,23 @@ module RuboCop
|
|
26
26
|
MSG = 'Prefer using verifying doubles over normal doubles.'.freeze
|
27
27
|
|
28
28
|
def_node_matcher :unverified_double, <<-PATTERN
|
29
|
-
{(send nil? {:double :spy}
|
29
|
+
{(send nil? {:double :spy} $...)}
|
30
30
|
PATTERN
|
31
31
|
|
32
32
|
def on_send(node)
|
33
|
-
unverified_double(node) do |name|
|
34
|
-
return if name.
|
33
|
+
unverified_double(node) do |name, *_args|
|
34
|
+
return if name.nil? && cop_config['IgnoreNameless']
|
35
|
+
return if symbol?(name) && cop_config['IgnoreSymbolicNames']
|
35
36
|
|
36
37
|
add_offense(node, location: :expression)
|
37
38
|
end
|
38
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def symbol?(name)
|
44
|
+
name && name.sym_type?
|
45
|
+
end
|
39
46
|
end
|
40
47
|
end
|
41
48
|
end
|
@@ -25,11 +25,13 @@ module RuboCop
|
|
25
25
|
|
26
26
|
def on_send(node)
|
27
27
|
return unless expect?(node)
|
28
|
+
|
28
29
|
check_expect(node)
|
29
30
|
end
|
30
31
|
|
31
32
|
def on_block(node)
|
32
33
|
return unless expect_block?(node)
|
34
|
+
|
33
35
|
check_expect(node)
|
34
36
|
end
|
35
37
|
|
@@ -37,6 +39,7 @@ module RuboCop
|
|
37
39
|
|
38
40
|
def check_expect(node)
|
39
41
|
return unless void?(node)
|
42
|
+
|
40
43
|
add_offense(node, location: :expression)
|
41
44
|
end
|
42
45
|
|
@@ -72,5 +72,6 @@ require_relative 'rspec/shared_context'
|
|
72
72
|
require_relative 'rspec/shared_examples'
|
73
73
|
require_relative 'rspec/single_argument_message_chain'
|
74
74
|
require_relative 'rspec/subject_stub'
|
75
|
+
require_relative 'rspec/unspecified_exception'
|
75
76
|
require_relative 'rspec/verified_doubles'
|
76
77
|
require_relative 'rspec/void_expect'
|
@@ -3,13 +3,16 @@ RSpec.describe 'config/default.yml' do
|
|
3
3
|
RuboCop::ConfigLoader.load_file('config/default.yml')
|
4
4
|
end
|
5
5
|
|
6
|
-
let(:
|
7
|
-
|
6
|
+
let(:namespaces) do
|
7
|
+
{
|
8
8
|
'rspec' => 'RSpec',
|
9
9
|
'capybara' => 'Capybara',
|
10
10
|
'factory_bot' => 'FactoryBot',
|
11
11
|
'rails' => 'Rails'
|
12
12
|
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:cop_names) do
|
13
16
|
glob = SpecHelper::ROOT.join('lib', 'rubocop', 'cop', 'rspec',
|
14
17
|
'{,capybara,factory_bot,rails}', '*.rb')
|
15
18
|
cop_names =
|
@@ -38,7 +41,17 @@ RSpec.describe 'config/default.yml' do
|
|
38
41
|
end
|
39
42
|
|
40
43
|
it 'has configuration for all cops' do
|
41
|
-
expect(default_config.keys
|
44
|
+
expect(default_config.keys).to match_array(config_keys)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'sorts configuration keys alphabetically' do
|
48
|
+
namespaces.each do |_path, prefix|
|
49
|
+
expected = config_keys.select { |key| key.start_with?(prefix) }.sort
|
50
|
+
actual = default_config.keys.select { |key| key.start_with?(prefix) }
|
51
|
+
actual.each_with_index do |key, idx|
|
52
|
+
expect(key).to eq expected[idx]
|
53
|
+
end
|
54
|
+
end
|
42
55
|
end
|
43
56
|
|
44
57
|
it 'has descriptions for all cops' do
|
@@ -133,6 +133,7 @@ RSpec.describe RuboCop::Cop::RSpec::FactoryBot::AttributeDefinedStatically do #
|
|
133
133
|
meta_tags(foo: Time.current)
|
134
134
|
other_tags({ foo: Time.current })
|
135
135
|
options color: :blue
|
136
|
+
other_options Tag::MAGIC => :magic
|
136
137
|
self.end Date.tomorrow
|
137
138
|
|
138
139
|
trait :old do
|
@@ -157,6 +158,7 @@ RSpec.describe RuboCop::Cop::RSpec::FactoryBot::AttributeDefinedStatically do #
|
|
157
158
|
meta_tags { { foo: Time.current } }
|
158
159
|
other_tags { { foo: Time.current } }
|
159
160
|
options { { color: :blue } }
|
161
|
+
other_options { { Tag::MAGIC => :magic } }
|
160
162
|
self.end { Date.tomorrow }
|
161
163
|
|
162
164
|
trait :old do
|
@@ -17,6 +17,14 @@ RSpec.describe RuboCop::Cop::RSpec::ImplicitSubject, :config do
|
|
17
17
|
RUBY
|
18
18
|
end
|
19
19
|
|
20
|
+
it 'allows `is_expected` inside `its` block, in multi-line examples' do
|
21
|
+
expect_no_offenses(<<-RUBY)
|
22
|
+
its(:quality) do
|
23
|
+
is_expected.to be :high
|
24
|
+
end
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
|
20
28
|
it 'flags `should` in multi-line examples' do
|
21
29
|
expect_offense(<<-RUBY)
|
22
30
|
it 'expect subject to be used' do
|
@@ -92,6 +100,50 @@ RSpec.describe RuboCop::Cop::RSpec::ImplicitSubject, :config do
|
|
92
100
|
good_code
|
93
101
|
end
|
94
102
|
|
103
|
+
context 'with EnforcedStyle `single_statement_only`' do
|
104
|
+
let(:enforced_style) { 'single_statement_only' }
|
105
|
+
|
106
|
+
it 'allows `is_expected` in multi-line example with single statement' do
|
107
|
+
expect_no_offenses(<<-RUBY)
|
108
|
+
it 'expect subject to be used' do
|
109
|
+
is_expected.to be_good
|
110
|
+
end
|
111
|
+
RUBY
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'flags `is_expected` in multi-statement examples' do
|
115
|
+
expect_offense(<<-RUBY)
|
116
|
+
it 'expect subject to be used' do
|
117
|
+
subject.age = 18
|
118
|
+
is_expected.to be_valid
|
119
|
+
^^^^^^^^^^^ Don't use implicit subject.
|
120
|
+
end
|
121
|
+
RUBY
|
122
|
+
end
|
123
|
+
|
124
|
+
bad_code = <<-RUBY
|
125
|
+
it 'is valid' do
|
126
|
+
subject.age = 18
|
127
|
+
is_expected.to be_valid
|
128
|
+
end
|
129
|
+
RUBY
|
130
|
+
|
131
|
+
good_code = <<-RUBY
|
132
|
+
it 'is valid' do
|
133
|
+
subject.age = 18
|
134
|
+
expect(subject).to be_valid
|
135
|
+
end
|
136
|
+
RUBY
|
137
|
+
|
138
|
+
include_examples 'autocorrect',
|
139
|
+
bad_code,
|
140
|
+
good_code
|
141
|
+
|
142
|
+
include_examples 'autocorrect',
|
143
|
+
bad_code,
|
144
|
+
good_code
|
145
|
+
end
|
146
|
+
|
95
147
|
context 'with EnforcedStyle `disallow`' do
|
96
148
|
let(:enforced_style) { 'disallow' }
|
97
149
|
|
@@ -127,6 +179,12 @@ RSpec.describe RuboCop::Cop::RSpec::ImplicitSubject, :config do
|
|
127
179
|
RUBY
|
128
180
|
end
|
129
181
|
|
182
|
+
it 'allows `is_expected` inside `its` block' do
|
183
|
+
expect_no_offenses(<<-RUBY)
|
184
|
+
its(:quality) { is_expected.to be :high }
|
185
|
+
RUBY
|
186
|
+
end
|
187
|
+
|
130
188
|
include_examples 'autocorrect',
|
131
189
|
'it { is_expected.to be_truthy }',
|
132
190
|
'it { expect(subject).to be_truthy }'
|
@@ -0,0 +1,175 @@
|
|
1
|
+
RSpec.describe RuboCop::Cop::RSpec::UnspecifiedException do
|
2
|
+
subject(:cop) { described_class.new }
|
3
|
+
|
4
|
+
context 'with raise_error matcher' do
|
5
|
+
it 'detects the `unspecified_exception` offense' do
|
6
|
+
expect_offense(<<-RUBY)
|
7
|
+
expect {
|
8
|
+
raise StandardError
|
9
|
+
}.to raise_error
|
10
|
+
^^^^^^^^^^^ Specify the exception being captured
|
11
|
+
RUBY
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'allows empty exception specification when not expecting an error' do
|
15
|
+
expect_no_offenses(<<-RUBY)
|
16
|
+
expect {
|
17
|
+
raise StandardError
|
18
|
+
}.not_to raise_error
|
19
|
+
RUBY
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'allows exception classes' do
|
23
|
+
expect_no_offenses(<<-RUBY)
|
24
|
+
expect {
|
25
|
+
raise StandardError
|
26
|
+
}.to raise_error(StandardError)
|
27
|
+
RUBY
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'allows exception messages' do
|
31
|
+
expect_no_offenses(<<-RUBY)
|
32
|
+
expect {
|
33
|
+
raise StandardError.new('error')
|
34
|
+
}.to raise_error('error')
|
35
|
+
RUBY
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'allows exception types with messages' do
|
39
|
+
expect_no_offenses(<<-RUBY)
|
40
|
+
expect {
|
41
|
+
raise StandardError.new('error')
|
42
|
+
}.to raise_error(StandardError, 'error')
|
43
|
+
RUBY
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'allows exception matching regular expressions' do
|
47
|
+
expect_no_offenses(<<-RUBY)
|
48
|
+
expect {
|
49
|
+
raise StandardError.new('error')
|
50
|
+
}.to raise_error(/err/)
|
51
|
+
RUBY
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'allows exception types with matching regular expressions' do
|
55
|
+
expect_no_offenses(<<-RUBY)
|
56
|
+
expect {
|
57
|
+
raise StandardError.new('error')
|
58
|
+
}.to raise_error(StandardError, /err/)
|
59
|
+
RUBY
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'allows classes with blocks with braces' do
|
63
|
+
expect_no_offenses(<<-RUBY)
|
64
|
+
expect {
|
65
|
+
raise StandardError.new('error')
|
66
|
+
}.to raise_error { |err| err.data }
|
67
|
+
RUBY
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'allows classes with blocks with do/end' do
|
71
|
+
expect_no_offenses(<<-RUBY)
|
72
|
+
expect {
|
73
|
+
raise StandardError.new('error')
|
74
|
+
}.to raise_error do |error|
|
75
|
+
error.data
|
76
|
+
end
|
77
|
+
RUBY
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'allows parameterized exceptions' do
|
81
|
+
expect_no_offenses(<<-RUBY)
|
82
|
+
my_exception = StandardError.new('my exception')
|
83
|
+
expect {
|
84
|
+
raise my_exception
|
85
|
+
}.to raise_error(my_exception)
|
86
|
+
RUBY
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'with raise_exception matcher' do
|
91
|
+
it 'detects the `unspecified_exception` offense' do
|
92
|
+
expect_offense(<<-RUBY)
|
93
|
+
expect {
|
94
|
+
raise StandardError
|
95
|
+
}.to raise_exception
|
96
|
+
^^^^^^^^^^^^^^^ Specify the exception being captured
|
97
|
+
RUBY
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'allows empty exception specification when not expecting an error' do
|
101
|
+
expect_no_offenses(<<-RUBY)
|
102
|
+
expect {
|
103
|
+
raise StandardError
|
104
|
+
}.not_to raise_exception
|
105
|
+
RUBY
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'allows exception classes' do
|
109
|
+
expect_no_offenses(<<-RUBY)
|
110
|
+
expect {
|
111
|
+
raise StandardError
|
112
|
+
}.to raise_exception(StandardError)
|
113
|
+
RUBY
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'allows exception messages' do
|
117
|
+
expect_no_offenses(<<-RUBY)
|
118
|
+
expect {
|
119
|
+
raise StandardError.new('error')
|
120
|
+
}.to raise_exception('error')
|
121
|
+
RUBY
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'allows exception types with messages' do
|
125
|
+
expect_no_offenses(<<-RUBY)
|
126
|
+
expect {
|
127
|
+
raise StandardError.new('error')
|
128
|
+
}.to raise_exception(StandardError, 'error')
|
129
|
+
RUBY
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'allows exception matching regular expressions' do
|
133
|
+
expect_no_offenses(<<-RUBY)
|
134
|
+
expect {
|
135
|
+
raise StandardError.new('error')
|
136
|
+
}.to raise_exception(/err/)
|
137
|
+
RUBY
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'allows exception types with matching regular expressions' do
|
141
|
+
expect_no_offenses(<<-RUBY)
|
142
|
+
expect {
|
143
|
+
raise StandardError.new('error')
|
144
|
+
}.to raise_exception(StandardError, /err/)
|
145
|
+
RUBY
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'allows classes with blocks with braces' do
|
149
|
+
expect_no_offenses(<<-RUBY)
|
150
|
+
expect {
|
151
|
+
raise StandardError.new('error')
|
152
|
+
}.to raise_exception { |err| err.data }
|
153
|
+
RUBY
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'allows classes with blocks with do/end' do
|
157
|
+
expect_no_offenses(<<-RUBY)
|
158
|
+
expect {
|
159
|
+
raise StandardError.new('error')
|
160
|
+
}.to raise_exception do |error|
|
161
|
+
error.data
|
162
|
+
end
|
163
|
+
RUBY
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'allows parameterized exceptions' do
|
167
|
+
expect_no_offenses(<<-RUBY)
|
168
|
+
my_exception = StandardError.new('my exception')
|
169
|
+
expect {
|
170
|
+
raise my_exception
|
171
|
+
}.to raise_exception(my_exception)
|
172
|
+
RUBY
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -53,14 +53,27 @@ RSpec.describe RuboCop::Cop::RSpec::VerifiedDoubles, :config do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
it '
|
57
|
-
|
56
|
+
it 'doubles that have no name specified' do
|
57
|
+
expect_offense(<<-RUBY)
|
58
58
|
it do
|
59
59
|
foo = double
|
60
|
+
^^^^^^ Prefer using verifying doubles over normal doubles.
|
60
61
|
end
|
61
62
|
RUBY
|
62
63
|
end
|
63
64
|
|
65
|
+
context 'when configured to ignore nameless doubles' do
|
66
|
+
let(:cop_config) { { 'IgnoreNameless' => true } }
|
67
|
+
|
68
|
+
it 'ignores doubles that have no name specified' do
|
69
|
+
expect_no_offenses(<<-RUBY)
|
70
|
+
it do
|
71
|
+
foo = double
|
72
|
+
end
|
73
|
+
RUBY
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
64
77
|
it 'ignores instance_doubles' do
|
65
78
|
expect_no_offenses(<<-RUBY)
|
66
79
|
it do
|
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.30.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: 2018-
|
13
|
+
date: 2018-10-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rubocop
|
@@ -184,19 +184,18 @@ files:
|
|
184
184
|
- lib/rubocop/cop/rspec/shared_examples.rb
|
185
185
|
- lib/rubocop/cop/rspec/single_argument_message_chain.rb
|
186
186
|
- lib/rubocop/cop/rspec/subject_stub.rb
|
187
|
+
- lib/rubocop/cop/rspec/unspecified_exception.rb
|
187
188
|
- lib/rubocop/cop/rspec/verified_doubles.rb
|
188
189
|
- lib/rubocop/cop/rspec/void_expect.rb
|
189
190
|
- lib/rubocop/cop/rspec_cops.rb
|
190
191
|
- lib/rubocop/rspec.rb
|
191
192
|
- lib/rubocop/rspec/align_let_brace.rb
|
192
193
|
- lib/rubocop/rspec/blank_line_separation.rb
|
193
|
-
- lib/rubocop/rspec/capybara.rb
|
194
194
|
- lib/rubocop/rspec/concept.rb
|
195
195
|
- lib/rubocop/rspec/config_formatter.rb
|
196
196
|
- lib/rubocop/rspec/description_extractor.rb
|
197
197
|
- lib/rubocop/rspec/example.rb
|
198
198
|
- lib/rubocop/rspec/example_group.rb
|
199
|
-
- lib/rubocop/rspec/factory_bot.rb
|
200
199
|
- lib/rubocop/rspec/final_end_location.rb
|
201
200
|
- lib/rubocop/rspec/hook.rb
|
202
201
|
- lib/rubocop/rspec/inject.rb
|
@@ -279,6 +278,7 @@ files:
|
|
279
278
|
- spec/rubocop/cop/rspec/shared_examples_spec.rb
|
280
279
|
- spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb
|
281
280
|
- spec/rubocop/cop/rspec/subject_stub_spec.rb
|
281
|
+
- spec/rubocop/cop/rspec/unspecified_exception_spec.rb
|
282
282
|
- spec/rubocop/cop/rspec/verified_doubles_spec.rb
|
283
283
|
- spec/rubocop/cop/rspec/void_expect_spec.rb
|
284
284
|
- spec/rubocop/rspec/config_formatter_spec.rb
|
@@ -396,6 +396,7 @@ test_files:
|
|
396
396
|
- spec/rubocop/cop/rspec/shared_examples_spec.rb
|
397
397
|
- spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb
|
398
398
|
- spec/rubocop/cop/rspec/subject_stub_spec.rb
|
399
|
+
- spec/rubocop/cop/rspec/unspecified_exception_spec.rb
|
399
400
|
- spec/rubocop/cop/rspec/verified_doubles_spec.rb
|
400
401
|
- spec/rubocop/cop/rspec/void_expect_spec.rb
|
401
402
|
- spec/rubocop/rspec/config_formatter_spec.rb
|