rubocop-rspec 3.9.0 → 3.10.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/config/default.yml +14 -0
- data/lib/rubocop/cop/rspec/around_block.rb +22 -0
- data/lib/rubocop/cop/rspec/contain_exactly.rb +8 -22
- data/lib/rubocop/cop/rspec/context_method.rb +1 -1
- data/lib/rubocop/cop/rspec/context_wording.rb +1 -1
- data/lib/rubocop/cop/rspec/described_class.rb +1 -1
- data/lib/rubocop/cop/rspec/discarded_matcher.rb +113 -0
- data/lib/rubocop/cop/rspec/empty_example_group.rb +3 -2
- data/lib/rubocop/cop/rspec/empty_hook.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +7 -2
- data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +1 -0
- data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/example_length.rb +1 -1
- data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
- data/lib/rubocop/cop/rspec/example_wording.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_actual.rb +33 -13
- data/lib/rubocop/cop/rspec/expect_change.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -0
- data/lib/rubocop/cop/rspec/expect_in_let.rb +1 -1
- data/lib/rubocop/cop/rspec/hook_argument.rb +1 -0
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +1 -0
- data/lib/rubocop/cop/rspec/indexed_let.rb +1 -1
- data/lib/rubocop/cop/rspec/instance_spy.rb +1 -1
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +13 -0
- data/lib/rubocop/cop/rspec/leading_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/let_before_examples.rb +1 -1
- data/lib/rubocop/cop/rspec/let_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/match_with_simple_regex.rb +89 -0
- data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
- data/lib/rubocop/cop/rspec/mixin/inside_example.rb +16 -0
- data/lib/rubocop/cop/rspec/mixin/metadata.rb +1 -0
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_subjects.rb +1 -1
- data/lib/rubocop/cop/rspec/named_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/no_expectation_example.rb +1 -0
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +1 -1
- data/lib/rubocop/cop/rspec/redundant_around.rb +1 -0
- data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
- data/lib/rubocop/cop/rspec/repeated_example.rb +1 -1
- data/lib/rubocop/cop/rspec/return_from_stub.rb +1 -1
- data/lib/rubocop/cop/rspec/scattered_let.rb +11 -5
- data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/shared_context.rb +1 -1
- data/lib/rubocop/cop/rspec/skip_block_inside_example.rb +3 -6
- data/lib/rubocop/cop/rspec/spec_file_path_format.rb +17 -10
- data/lib/rubocop/cop/rspec/subject_declaration.rb +17 -1
- data/lib/rubocop/cop/rspec/undescriptive_literals_description.rb +1 -1
- data/lib/rubocop/cop/rspec/void_expect.rb +3 -5
- data/lib/rubocop/cop/rspec/yield.rb +1 -1
- data/lib/rubocop/cop/rspec_cops.rb +2 -0
- data/lib/rubocop/rspec/description_extractor.rb +1 -1
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop-rspec.rb +1 -0
- metadata +27 -4
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'regexp_parser'
|
|
4
|
+
|
|
5
|
+
module RuboCop
|
|
6
|
+
module Cop
|
|
7
|
+
module RSpec
|
|
8
|
+
# Enforces the use of `include` matcher instead of `match` when the
|
|
9
|
+
# matcher is a simple string literal without regex-specific features.
|
|
10
|
+
#
|
|
11
|
+
# When `match` is used with a regex that contains only literal characters
|
|
12
|
+
# (no anchors, character classes, quantifiers, alternations, or
|
|
13
|
+
# metacharacters), it's clearer to use the `include` matcher instead.
|
|
14
|
+
#
|
|
15
|
+
# @example
|
|
16
|
+
# # bad
|
|
17
|
+
# expect('foobar').to match(/foo/)
|
|
18
|
+
# expect(response.body).to match(/http:\/\/example\.com/)
|
|
19
|
+
#
|
|
20
|
+
# # good
|
|
21
|
+
# expect('foobar').to include('foo')
|
|
22
|
+
# expect(response.body).to include('http://example.com')
|
|
23
|
+
#
|
|
24
|
+
# # good - regex features needed
|
|
25
|
+
# expect('foobar').to match(/^foo/) # anchor
|
|
26
|
+
# expect('foobar').to match(/foo\d+/) # quantifier
|
|
27
|
+
# expect('foobar').to match(/foo[ob]/) # character class
|
|
28
|
+
#
|
|
29
|
+
class MatchWithSimpleRegex < Base
|
|
30
|
+
extend AutoCorrector
|
|
31
|
+
|
|
32
|
+
MSG = 'Prefer using `include(%<string>s)` when the regex is a simple ' \
|
|
33
|
+
'string literal.'
|
|
34
|
+
RESTRICT_ON_SEND = %i[match].freeze
|
|
35
|
+
|
|
36
|
+
# @!method match_with_regexp?(node)
|
|
37
|
+
def_node_matcher :match_with_regexp?, <<~PATTERN
|
|
38
|
+
(send nil? :match $regexp)
|
|
39
|
+
PATTERN
|
|
40
|
+
|
|
41
|
+
def on_send(node)
|
|
42
|
+
match_with_regexp?(node) do |regexp|
|
|
43
|
+
next unless simple_regexp?(regexp)
|
|
44
|
+
|
|
45
|
+
string_literal = regexp_to_string(regexp)
|
|
46
|
+
message = format(MSG, string: string_literal)
|
|
47
|
+
|
|
48
|
+
add_offense(node, message: message) do |corrector|
|
|
49
|
+
corrector.replace(node, "include(#{string_literal})")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def simple_regexp?(node)
|
|
57
|
+
parsed = Regexp::Parser.parse(node.content)
|
|
58
|
+
parsed.expressions.all? { |expr| simple_expression?(expr) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def simple_expression?(expr)
|
|
62
|
+
return false if expr.quantified?
|
|
63
|
+
return true if expr.is_a?(Regexp::Expression::Literal)
|
|
64
|
+
return true if expr.is_a?(Regexp::Expression::EscapeSequence::Literal)
|
|
65
|
+
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Reconstruct the literal string that the regex matches
|
|
70
|
+
def regexp_to_string(node)
|
|
71
|
+
parsed = Regexp::Parser.parse(node.content)
|
|
72
|
+
string_content = parsed.expressions.map do |expr|
|
|
73
|
+
expr.respond_to?(:char) ? expr.char : expr.text
|
|
74
|
+
end.join
|
|
75
|
+
|
|
76
|
+
to_string_literal(string_content)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def to_string_literal(string)
|
|
80
|
+
if string.include?("'")
|
|
81
|
+
%("#{string.gsub('"', '\"')}")
|
|
82
|
+
else
|
|
83
|
+
"'#{string}'"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
|
23
23
|
class MissingExampleGroupArgument < Base
|
|
24
24
|
MSG = 'The first argument to `%<method>s` should not be empty.'
|
|
25
25
|
|
|
26
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
26
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
27
27
|
return unless example_group?(node)
|
|
28
28
|
return if node.send_node.arguments?
|
|
29
29
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RSpec
|
|
6
|
+
# Helps check if a given node is within an example block.
|
|
7
|
+
module InsideExample
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def inside_example?(node)
|
|
11
|
+
node.each_ancestor(:block).any? { |ancestor| example?(ancestor) }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -90,7 +90,7 @@ module RuboCop
|
|
|
90
90
|
(block (send nil? :aggregate_failures ...) ...)
|
|
91
91
|
PATTERN
|
|
92
92
|
|
|
93
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
93
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
94
94
|
return unless example?(node)
|
|
95
95
|
|
|
96
96
|
return if example_with_aggregate_failures?(node)
|
|
@@ -88,7 +88,7 @@ module RuboCop
|
|
|
88
88
|
|
|
89
89
|
exclude_limit 'Max'
|
|
90
90
|
|
|
91
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
91
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
92
92
|
return unless spec_group?(node)
|
|
93
93
|
|
|
94
94
|
count = all_helpers(node).uniq.count
|
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
|
54
54
|
|
|
55
55
|
MSG = 'Do not set more than one subject per example group'
|
|
56
56
|
|
|
57
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
57
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
58
58
|
return unless example_group?(node)
|
|
59
59
|
|
|
60
60
|
subjects = RuboCop::RSpec::ExampleGroup.new(node).subjects
|
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
|
94
94
|
# @!method subject_usage(node)
|
|
95
95
|
def_node_search :subject_usage, '$(send nil? :subject)'
|
|
96
96
|
|
|
97
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
97
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
98
98
|
if !example_or_hook_block?(node) || ignored_shared_example?(node)
|
|
99
99
|
return
|
|
100
100
|
end
|
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
|
33
33
|
# @!method first_argument_name(node)
|
|
34
34
|
def_node_matcher :first_argument_name, '(send _ _ ({str sym} $_))'
|
|
35
35
|
|
|
36
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
36
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
37
37
|
return unless example_group_with_body?(node)
|
|
38
38
|
|
|
39
39
|
find_duplicates(node.body) do |duplicate, name|
|
|
@@ -340,7 +340,7 @@ module RuboCop
|
|
|
340
340
|
end
|
|
341
341
|
end
|
|
342
342
|
|
|
343
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
343
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
344
344
|
check_explicit(node) if style == :explicit
|
|
345
345
|
end
|
|
346
346
|
end
|
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
|
42
42
|
class RepeatedDescription < Base
|
|
43
43
|
MSG = "Don't repeat descriptions within an example group."
|
|
44
44
|
|
|
45
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
45
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
46
46
|
return unless example_group?(node)
|
|
47
47
|
|
|
48
48
|
repeated_descriptions(node).each do |description|
|
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
|
19
19
|
MSG = "Don't repeat examples within an example group. " \
|
|
20
20
|
'Repeated on line(s) %<lines>s.'
|
|
21
21
|
|
|
22
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
22
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
23
23
|
return unless example_group?(node)
|
|
24
24
|
|
|
25
25
|
find_repeated_examples(node).each do |repeated_examples|
|
|
@@ -59,7 +59,7 @@ module RuboCop
|
|
|
59
59
|
check_and_return_call(node)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
62
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
63
63
|
return unless style == :and_return
|
|
64
64
|
return unless stub_with_block?(node)
|
|
65
65
|
|
|
@@ -19,11 +19,11 @@ module RuboCop
|
|
|
19
19
|
#
|
|
20
20
|
# # good
|
|
21
21
|
# describe Foo do
|
|
22
|
-
# subject { Foo }
|
|
23
|
-
# before { prepare }
|
|
24
22
|
# let(:foo) { 1 }
|
|
25
23
|
# let(:bar) { 2 }
|
|
26
24
|
# let!(:baz) { 3 }
|
|
25
|
+
# subject { Foo }
|
|
26
|
+
# before { prepare }
|
|
27
27
|
# end
|
|
28
28
|
#
|
|
29
29
|
class ScatteredLet < Base
|
|
@@ -31,7 +31,7 @@ module RuboCop
|
|
|
31
31
|
|
|
32
32
|
MSG = 'Group all let/let! blocks in the example group together.'
|
|
33
33
|
|
|
34
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
34
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
35
35
|
return unless example_group_with_body?(node)
|
|
36
36
|
|
|
37
37
|
check_let_declarations(node.body)
|
|
@@ -41,15 +41,21 @@ module RuboCop
|
|
|
41
41
|
|
|
42
42
|
def check_let_declarations(body)
|
|
43
43
|
lets = body.each_child_node.select { |node| let?(node) }
|
|
44
|
+
return if lets.empty?
|
|
44
45
|
|
|
45
46
|
first_let = lets.first
|
|
47
|
+
reference_let = first_let
|
|
48
|
+
|
|
46
49
|
lets.each_with_index do |node, idx|
|
|
47
|
-
|
|
50
|
+
if node.sibling_index == first_let.sibling_index + idx
|
|
51
|
+
reference_let = node
|
|
52
|
+
next
|
|
53
|
+
end
|
|
48
54
|
|
|
49
55
|
add_offense(node) do |corrector|
|
|
50
56
|
RuboCop::RSpec::Corrector::MoveNode.new(
|
|
51
57
|
node, corrector, processed_source
|
|
52
|
-
).move_after(
|
|
58
|
+
).move_after(reference_let)
|
|
53
59
|
end
|
|
54
60
|
end
|
|
55
61
|
end
|
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
|
47
47
|
MSG = 'Do not define multiple `%<hook_name>s` hooks in the same ' \
|
|
48
48
|
'example group (also defined on %<lines>s).'
|
|
49
49
|
|
|
50
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
50
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
51
51
|
return unless example_group?(node)
|
|
52
52
|
|
|
53
53
|
repeated_hooks(node).each do |occurrences|
|
|
@@ -78,7 +78,7 @@ module RuboCop
|
|
|
78
78
|
(block (send #rspec? #SharedGroups.examples ...) ...)
|
|
79
79
|
PATTERN
|
|
80
80
|
|
|
81
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
81
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
82
82
|
context_with_only_examples(node) do
|
|
83
83
|
add_offense(node.send_node, message: MSG_EXAMPLES) do |corrector|
|
|
84
84
|
corrector.replace(node.send_node.loc.selector, 'shared_examples')
|
|
@@ -24,6 +24,8 @@ module RuboCop
|
|
|
24
24
|
# end
|
|
25
25
|
#
|
|
26
26
|
class SkipBlockInsideExample < Base
|
|
27
|
+
include InsideExample
|
|
28
|
+
|
|
27
29
|
MSG = "Don't pass a block to `skip` inside examples."
|
|
28
30
|
|
|
29
31
|
def on_block(node)
|
|
@@ -34,12 +36,7 @@ module RuboCop
|
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
alias on_numblock on_block
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def inside_example?(node)
|
|
41
|
-
node.each_ancestor(:block).any? { |ancestor| example?(ancestor) }
|
|
42
|
-
end
|
|
39
|
+
alias on_itblock on_block
|
|
43
40
|
end
|
|
44
41
|
end
|
|
45
42
|
end
|
|
@@ -44,6 +44,7 @@ module RuboCop
|
|
|
44
44
|
include FileHelp
|
|
45
45
|
|
|
46
46
|
MSG = 'Spec path should end with `%<suffix>s`.'
|
|
47
|
+
PATH_NAME_BOUNDARY = '(?![[:alnum:]])'
|
|
47
48
|
|
|
48
49
|
# @!method example_group_arguments(node)
|
|
49
50
|
def_node_matcher :example_group_arguments, <<~PATTERN
|
|
@@ -119,7 +120,11 @@ module RuboCop
|
|
|
119
120
|
# For the suffix shown in the offense message, modify the regular
|
|
120
121
|
# expression pattern to resemble a glob pattern for clearer error
|
|
121
122
|
# messages.
|
|
122
|
-
suffix = pattern
|
|
123
|
+
suffix = pattern
|
|
124
|
+
.sub(PATH_NAME_BOUNDARY, '')
|
|
125
|
+
.sub('.*', '*')
|
|
126
|
+
.sub('[^/]*', '*')
|
|
127
|
+
.sub('\.', '.')
|
|
123
128
|
add_offense(send_node, message: format(MSG, suffix: suffix))
|
|
124
129
|
end
|
|
125
130
|
|
|
@@ -132,19 +137,21 @@ module RuboCop
|
|
|
132
137
|
end
|
|
133
138
|
|
|
134
139
|
def correct_path_pattern(class_name, arguments)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
[
|
|
141
|
+
expected_path(class_name),
|
|
142
|
+
PATH_NAME_BOUNDARY,
|
|
143
|
+
method_name_pattern(arguments.first),
|
|
144
|
+
'[^/]*_spec\.rb'
|
|
145
|
+
].join
|
|
139
146
|
end
|
|
140
147
|
|
|
141
|
-
def
|
|
142
|
-
return if
|
|
148
|
+
def method_name_pattern(method_name)
|
|
149
|
+
return if ignore_method_name?(method_name)
|
|
143
150
|
|
|
144
|
-
method_name.str_content.gsub(/\s/, '_').gsub(/\W/, '')
|
|
151
|
+
".*#{method_name.str_content.gsub(/\s/, '_').gsub(/\W/, '')}"
|
|
145
152
|
end
|
|
146
153
|
|
|
147
|
-
def
|
|
154
|
+
def ignore_method_name?(method_name)
|
|
148
155
|
!method_name&.str_type? || ignore_methods?
|
|
149
156
|
end
|
|
150
157
|
|
|
@@ -175,7 +182,7 @@ module RuboCop
|
|
|
175
182
|
end
|
|
176
183
|
|
|
177
184
|
def filename_ends_with?(pattern)
|
|
178
|
-
expanded_file_path.match?(
|
|
185
|
+
expanded_file_path.match?(%r{(?:\A|/)#{pattern}$})
|
|
179
186
|
end
|
|
180
187
|
end
|
|
181
188
|
end
|
|
@@ -20,6 +20,8 @@ module RuboCop
|
|
|
20
20
|
# subject(:test_subject) { foo }
|
|
21
21
|
#
|
|
22
22
|
class SubjectDeclaration < Base
|
|
23
|
+
extend AutoCorrector
|
|
24
|
+
|
|
23
25
|
MSG_LET = 'Use subject explicitly rather than using let'
|
|
24
26
|
MSG_REDUNDANT = 'Ambiguous declaration of subject'
|
|
25
27
|
|
|
@@ -32,7 +34,11 @@ module RuboCop
|
|
|
32
34
|
offense = offensive_subject_declaration?(node)
|
|
33
35
|
return unless offense
|
|
34
36
|
|
|
35
|
-
add_offense(node, message: message_for(offense))
|
|
37
|
+
add_offense(node, message: message_for(offense)) do |corrector|
|
|
38
|
+
corrector.replace(node.loc.selector,
|
|
39
|
+
node.method_name.to_s.sub('let', 'subject'))
|
|
40
|
+
corrector.remove(first_argument_range(node))
|
|
41
|
+
end
|
|
36
42
|
end
|
|
37
43
|
|
|
38
44
|
private
|
|
@@ -40,6 +46,16 @@ module RuboCop
|
|
|
40
46
|
def message_for(offense)
|
|
41
47
|
Helpers.all(offense) ? MSG_LET : MSG_REDUNDANT
|
|
42
48
|
end
|
|
49
|
+
|
|
50
|
+
def first_argument_range(node)
|
|
51
|
+
if node.arguments.one?
|
|
52
|
+
node.loc.begin.join(node.loc.end)
|
|
53
|
+
else
|
|
54
|
+
node.first_argument.source_range.with(
|
|
55
|
+
end_pos: node.arguments[1].source_range.begin_pos
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
43
59
|
end
|
|
44
60
|
end
|
|
45
61
|
end
|
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
|
52
52
|
(block (send #rspec? {#ExampleGroups.all #Examples.all} $_) ...)
|
|
53
53
|
PATTERN
|
|
54
54
|
|
|
55
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
55
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
56
56
|
example_groups_or_example?(node) do |arg|
|
|
57
57
|
add_offense(arg) if offense?(arg)
|
|
58
58
|
end
|
|
@@ -13,6 +13,8 @@ module RuboCop
|
|
|
13
13
|
# expect(something).to be(1)
|
|
14
14
|
#
|
|
15
15
|
class VoidExpect < Base
|
|
16
|
+
include InsideExample
|
|
17
|
+
|
|
16
18
|
MSG = 'Do not use `expect()` without `.to` or `.not_to`. ' \
|
|
17
19
|
'Chain the methods or remove it.'
|
|
18
20
|
RESTRICT_ON_SEND = %i[expect].freeze
|
|
@@ -34,7 +36,7 @@ module RuboCop
|
|
|
34
36
|
check_expect(node)
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
39
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
38
40
|
return unless expect_block?(node)
|
|
39
41
|
return unless inside_example?(node)
|
|
40
42
|
|
|
@@ -55,10 +57,6 @@ module RuboCop
|
|
|
55
57
|
|
|
56
58
|
parent.block_type? && parent.body == expect
|
|
57
59
|
end
|
|
58
|
-
|
|
59
|
-
def inside_example?(node)
|
|
60
|
-
node.each_ancestor(:block).any? { |ancestor| example?(ancestor) }
|
|
61
|
-
end
|
|
62
60
|
end
|
|
63
61
|
end
|
|
64
62
|
end
|
|
@@ -27,7 +27,7 @@ module RuboCop
|
|
|
27
27
|
# @!method block_call?(node)
|
|
28
28
|
def_node_matcher :block_call?, '(send (lvar %) :call ...)'
|
|
29
29
|
|
|
30
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
30
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
31
31
|
return unless method_on_stub?(node.send_node)
|
|
32
32
|
|
|
33
33
|
block_arg(node.arguments) do |block|
|
|
@@ -21,6 +21,7 @@ require_relative 'rspec/describe_symbol'
|
|
|
21
21
|
require_relative 'rspec/described_class'
|
|
22
22
|
require_relative 'rspec/described_class_module_wrapping'
|
|
23
23
|
require_relative 'rspec/dialect'
|
|
24
|
+
require_relative 'rspec/discarded_matcher'
|
|
24
25
|
require_relative 'rspec/duplicated_metadata'
|
|
25
26
|
require_relative 'rspec/empty_example_group'
|
|
26
27
|
require_relative 'rspec/empty_hook'
|
|
@@ -61,6 +62,7 @@ require_relative 'rspec/leaky_local_variable'
|
|
|
61
62
|
require_relative 'rspec/let_before_examples'
|
|
62
63
|
require_relative 'rspec/let_setup'
|
|
63
64
|
require_relative 'rspec/match_array'
|
|
65
|
+
require_relative 'rspec/match_with_simple_regex'
|
|
64
66
|
require_relative 'rspec/message_chain'
|
|
65
67
|
require_relative 'rspec/message_expectation'
|
|
66
68
|
require_relative 'rspec/message_spies'
|
data/lib/rubocop-rspec.rb
CHANGED
|
@@ -14,6 +14,7 @@ require_relative 'rubocop/rspec/wording'
|
|
|
14
14
|
|
|
15
15
|
require_relative 'rubocop/cop/rspec/mixin/file_help'
|
|
16
16
|
require_relative 'rubocop/cop/rspec/mixin/final_end_location'
|
|
17
|
+
require_relative 'rubocop/cop/rspec/mixin/inside_example'
|
|
17
18
|
require_relative 'rubocop/cop/rspec/mixin/inside_example_group'
|
|
18
19
|
require_relative 'rubocop/cop/rspec/mixin/location_help'
|
|
19
20
|
require_relative 'rubocop/cop/rspec/mixin/metadata'
|
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: 3.
|
|
4
|
+
version: 3.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John Backus
|
|
@@ -25,20 +25,40 @@ dependencies:
|
|
|
25
25
|
- - "~>"
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
27
|
version: '1.1'
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: regexp_parser
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - ">="
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '2.0'
|
|
35
|
+
type: :runtime
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '2.0'
|
|
28
42
|
- !ruby/object:Gem::Dependency
|
|
29
43
|
name: rubocop
|
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
|
31
45
|
requirements:
|
|
32
46
|
- - "~>"
|
|
33
47
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: '1.
|
|
48
|
+
version: '1.86'
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: 1.86.2
|
|
35
52
|
type: :runtime
|
|
36
53
|
prerelease: false
|
|
37
54
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
55
|
requirements:
|
|
39
56
|
- - "~>"
|
|
40
57
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: '1.
|
|
58
|
+
version: '1.86'
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 1.86.2
|
|
42
62
|
description: |
|
|
43
63
|
Code style checking for RSpec files.
|
|
44
64
|
A plugin for the RuboCop code style enforcing & linting tool.
|
|
@@ -81,6 +101,7 @@ files:
|
|
|
81
101
|
- lib/rubocop/cop/rspec/described_class.rb
|
|
82
102
|
- lib/rubocop/cop/rspec/described_class_module_wrapping.rb
|
|
83
103
|
- lib/rubocop/cop/rspec/dialect.rb
|
|
104
|
+
- lib/rubocop/cop/rspec/discarded_matcher.rb
|
|
84
105
|
- lib/rubocop/cop/rspec/duplicated_metadata.rb
|
|
85
106
|
- lib/rubocop/cop/rspec/empty_example_group.rb
|
|
86
107
|
- lib/rubocop/cop/rspec/empty_hook.rb
|
|
@@ -121,6 +142,7 @@ files:
|
|
|
121
142
|
- lib/rubocop/cop/rspec/let_before_examples.rb
|
|
122
143
|
- lib/rubocop/cop/rspec/let_setup.rb
|
|
123
144
|
- lib/rubocop/cop/rspec/match_array.rb
|
|
145
|
+
- lib/rubocop/cop/rspec/match_with_simple_regex.rb
|
|
124
146
|
- lib/rubocop/cop/rspec/message_chain.rb
|
|
125
147
|
- lib/rubocop/cop/rspec/message_expectation.rb
|
|
126
148
|
- lib/rubocop/cop/rspec/message_spies.rb
|
|
@@ -131,6 +153,7 @@ files:
|
|
|
131
153
|
- lib/rubocop/cop/rspec/mixin/empty_line_separation.rb
|
|
132
154
|
- lib/rubocop/cop/rspec/mixin/file_help.rb
|
|
133
155
|
- lib/rubocop/cop/rspec/mixin/final_end_location.rb
|
|
156
|
+
- lib/rubocop/cop/rspec/mixin/inside_example.rb
|
|
134
157
|
- lib/rubocop/cop/rspec/mixin/inside_example_group.rb
|
|
135
158
|
- lib/rubocop/cop/rspec/mixin/location_help.rb
|
|
136
159
|
- lib/rubocop/cop/rspec/mixin/metadata.rb
|
|
@@ -223,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
223
246
|
- !ruby/object:Gem::Version
|
|
224
247
|
version: '0'
|
|
225
248
|
requirements: []
|
|
226
|
-
rubygems_version: 4.0.
|
|
249
|
+
rubygems_version: 4.0.10
|
|
227
250
|
specification_version: 4
|
|
228
251
|
summary: Code style checking for RSpec files
|
|
229
252
|
test_files: []
|