rubocop-rspec 2.12.0 → 2.13.1
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 +118 -86
- data/config/default.yml +44 -6
- data/config/obsoletion.yml +14 -0
- data/lib/rubocop/cop/rspec/align_left_let_brace.rb +8 -9
- data/lib/rubocop/cop/rspec/align_right_let_brace.rb +8 -9
- data/lib/rubocop/cop/rspec/any_instance.rb +1 -0
- data/lib/rubocop/cop/rspec/around_block.rb +26 -3
- data/lib/rubocop/cop/rspec/be.rb +0 -1
- data/lib/rubocop/cop/rspec/be_eq.rb +0 -1
- data/lib/rubocop/cop/rspec/be_eql.rb +0 -1
- data/lib/rubocop/cop/rspec/before_after_all.rb +1 -0
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +9 -3
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +2 -1
- data/lib/rubocop/cop/rspec/capybara/specific_finders.rb +86 -0
- data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +91 -10
- data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +0 -1
- data/lib/rubocop/cop/rspec/change_by_zero.rb +60 -5
- data/lib/rubocop/cop/rspec/class_check.rb +101 -0
- data/lib/rubocop/cop/rspec/context_method.rb +2 -1
- data/lib/rubocop/cop/rspec/context_wording.rb +49 -18
- data/lib/rubocop/cop/rspec/describe_class.rb +1 -1
- data/lib/rubocop/cop/rspec/describe_method.rb +1 -0
- data/lib/rubocop/cop/rspec/described_class.rb +4 -14
- data/lib/rubocop/cop/rspec/dialect.rb +1 -0
- data/lib/rubocop/cop/rspec/empty_example_group.rb +19 -4
- data/lib/rubocop/cop/rspec/empty_hook.rb +2 -1
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +4 -9
- data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +1 -1
- data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +2 -1
- data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +32 -2
- data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +2 -1
- data/lib/rubocop/cop/rspec/example_length.rb +2 -1
- data/lib/rubocop/cop/rspec/example_without_description.rb +2 -1
- data/lib/rubocop/cop/rspec/example_wording.rb +2 -1
- data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +1 -0
- data/lib/rubocop/cop/rspec/expect_actual.rb +3 -0
- data/lib/rubocop/cop/rspec/expect_change.rb +1 -1
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +4 -1
- data/lib/rubocop/cop/rspec/expect_output.rb +1 -0
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +2 -1
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +26 -12
- data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -0
- data/lib/rubocop/cop/rspec/file_path.rb +6 -3
- data/lib/rubocop/cop/rspec/focus.rb +18 -0
- data/lib/rubocop/cop/rspec/hook_argument.rb +7 -2
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +10 -9
- data/lib/rubocop/cop/rspec/identical_equality_assertion.rb +0 -1
- data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -0
- data/lib/rubocop/cop/rspec/implicit_expect.rb +0 -2
- data/lib/rubocop/cop/rspec/instance_spy.rb +1 -1
- data/lib/rubocop/cop/rspec/instance_variable.rb +0 -1
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +1 -0
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +16 -0
- data/lib/rubocop/cop/rspec/leading_subject.rb +15 -15
- data/lib/rubocop/cop/rspec/let_before_examples.rb +7 -8
- data/lib/rubocop/cop/rspec/let_setup.rb +4 -4
- data/lib/rubocop/cop/rspec/message_chain.rb +1 -1
- data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +2 -1
- data/lib/rubocop/cop/rspec/mixin/css_selector.rb +99 -0
- data/lib/rubocop/cop/rspec/mixin/namespace.rb +23 -0
- data/lib/rubocop/cop/rspec/multiple_describes.rb +1 -0
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +1 -5
- data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +1 -3
- data/lib/rubocop/cop/rspec/multiple_subjects.rb +17 -2
- data/lib/rubocop/cop/rspec/named_subject.rb +2 -1
- data/lib/rubocop/cop/rspec/nested_groups.rb +45 -25
- data/lib/rubocop/cop/rspec/no_expectation_example.rb +64 -0
- data/lib/rubocop/cop/rspec/not_to_not.rb +1 -2
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +2 -1
- data/lib/rubocop/cop/rspec/pending.rb +1 -0
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +2 -1
- data/lib/rubocop/cop/rspec/rails/avoid_setup_hook.rb +1 -2
- data/lib/rubocop/cop/rspec/receive_counts.rb +14 -15
- data/lib/rubocop/cop/rspec/receive_never.rb +4 -5
- data/lib/rubocop/cop/rspec/repeated_description.rb +25 -26
- data/lib/rubocop/cop/rspec/repeated_example.rb +1 -1
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +28 -29
- data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +28 -29
- data/lib/rubocop/cop/rspec/repeated_include_example.rb +32 -33
- data/lib/rubocop/cop/rspec/return_from_stub.rb +1 -1
- data/lib/rubocop/cop/rspec/scattered_let.rb +1 -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/stubbed_mock.rb +0 -1
- data/lib/rubocop/cop/rspec/subject_declaration.rb +0 -1
- data/lib/rubocop/cop/rspec/subject_stub.rb +2 -2
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +15 -15
- data/lib/rubocop/cop/rspec/variable_definition.rb +1 -0
- data/lib/rubocop/cop/rspec/variable_name.rb +6 -7
- data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -0
- data/lib/rubocop/cop/rspec/void_expect.rb +2 -1
- data/lib/rubocop/cop/rspec/yield.rb +2 -1
- data/lib/rubocop/cop/rspec_cops.rb +3 -0
- data/lib/rubocop/rspec/config_formatter.rb +14 -3
- data/lib/rubocop/rspec/inject.rb +1 -3
- data/lib/rubocop/rspec/language/node_pattern.rb +4 -0
- data/lib/rubocop/rspec/language.rb +6 -1
- data/lib/rubocop/rspec/version.rb +1 -1
- data/lib/rubocop/rspec/wording.rb +2 -2
- data/lib/rubocop/rspec.rb +14 -0
- data/lib/rubocop-rspec.rb +3 -0
- metadata +11 -88
@@ -6,7 +6,6 @@ module RuboCop
|
|
6
6
|
# Checks if an example group does not include any tests.
|
7
7
|
#
|
8
8
|
# @example usage
|
9
|
-
#
|
10
9
|
# # bad
|
11
10
|
# describe Bacon do
|
12
11
|
# let(:bacon) { Bacon.new(chunkiness) }
|
@@ -35,7 +34,12 @@ module RuboCop
|
|
35
34
|
# describe Bacon do
|
36
35
|
# pending 'will add tests later'
|
37
36
|
# end
|
37
|
+
#
|
38
38
|
class EmptyExampleGroup < Base
|
39
|
+
extend AutoCorrector
|
40
|
+
|
41
|
+
include RangeHelp
|
42
|
+
|
39
43
|
MSG = 'Empty example group detected.'
|
40
44
|
|
41
45
|
# @!method example_group_body(node)
|
@@ -119,7 +123,7 @@ module RuboCop
|
|
119
123
|
# describe { it { i_run_as_well } }
|
120
124
|
#
|
121
125
|
# @example source that does not match
|
122
|
-
# before { it { whatever here
|
126
|
+
# before { it { whatever here won't run anyway } }
|
123
127
|
#
|
124
128
|
# @param node [RuboCop::AST::Node]
|
125
129
|
# @return [Array<RuboCop::AST::Node>] matching nodes
|
@@ -130,12 +134,16 @@ module RuboCop
|
|
130
134
|
}
|
131
135
|
PATTERN
|
132
136
|
|
133
|
-
def on_block(node)
|
137
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
134
138
|
return if node.each_ancestor(:def, :defs).any?
|
135
139
|
return if node.each_ancestor(:block).any? { |block| example?(block) }
|
136
140
|
|
137
141
|
example_group_body(node) do |body|
|
138
|
-
|
142
|
+
next unless offensive?(body)
|
143
|
+
|
144
|
+
add_offense(node.send_node) do |corrector|
|
145
|
+
corrector.remove(removed_range(node))
|
146
|
+
end
|
139
147
|
end
|
140
148
|
end
|
141
149
|
|
@@ -163,6 +171,13 @@ module RuboCop
|
|
163
171
|
def examples_in_branches?(condition_node)
|
164
172
|
condition_node.branches.any? { |branch| examples?(branch) }
|
165
173
|
end
|
174
|
+
|
175
|
+
def removed_range(node)
|
176
|
+
range_by_whole_lines(
|
177
|
+
node.location.expression,
|
178
|
+
include_final_newline: true
|
179
|
+
)
|
180
|
+
end
|
166
181
|
end
|
167
182
|
end
|
168
183
|
end
|
@@ -22,6 +22,7 @@ module RuboCop
|
|
22
22
|
# create_feed
|
23
23
|
# end
|
24
24
|
# after(:all) { cleanup_feed }
|
25
|
+
#
|
25
26
|
class EmptyHook < Base
|
26
27
|
extend AutoCorrector
|
27
28
|
include RuboCop::Cop::RangeHelp
|
@@ -33,7 +34,7 @@ module RuboCop
|
|
33
34
|
(block $#{send_pattern('#Hooks.all')} _ nil?)
|
34
35
|
PATTERN
|
35
36
|
|
36
|
-
def on_block(node)
|
37
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
37
38
|
empty_hook?(node) do |hook|
|
38
39
|
add_offense(hook) do |corrector|
|
39
40
|
corrector.remove(
|
@@ -30,7 +30,6 @@ module RuboCop
|
|
30
30
|
# end
|
31
31
|
#
|
32
32
|
# @example with AllowConsecutiveOneLiners configuration
|
33
|
-
#
|
34
33
|
# # rubocop.yml
|
35
34
|
# # RSpec/EmptyLineAfterExample:
|
36
35
|
# # AllowConsecutiveOneLiners: false
|
@@ -47,7 +46,7 @@ module RuboCop
|
|
47
46
|
|
48
47
|
MSG = 'Add an empty line after `%<example>s`.'
|
49
48
|
|
50
|
-
def on_block(node)
|
49
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
51
50
|
return unless example?(node)
|
52
51
|
return if allowed_one_liner?(node)
|
53
52
|
|
@@ -65,19 +64,15 @@ module RuboCop
|
|
65
64
|
end
|
66
65
|
|
67
66
|
def consecutive_one_liner?(node)
|
68
|
-
node.
|
67
|
+
node.single_line? && next_one_line_example?(node)
|
69
68
|
end
|
70
69
|
|
71
70
|
def next_one_line_example?(node)
|
72
|
-
next_sibling =
|
71
|
+
next_sibling = node.right_sibling
|
73
72
|
return unless next_sibling
|
74
73
|
return unless example?(next_sibling)
|
75
74
|
|
76
|
-
next_sibling.
|
77
|
-
end
|
78
|
-
|
79
|
-
def next_sibling(node)
|
80
|
-
node.parent.children[node.sibling_index + 1]
|
75
|
+
next_sibling.single_line?
|
81
76
|
end
|
82
77
|
end
|
83
78
|
end
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
|
30
30
|
MSG = 'Add an empty line after `%<example_group>s`.'
|
31
31
|
|
32
|
-
def on_block(node)
|
32
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
33
33
|
return unless example_group?(node)
|
34
34
|
|
35
35
|
missing_separating_line_offense(node) do |method|
|
@@ -16,13 +16,14 @@ module RuboCop
|
|
16
16
|
# let(:something) { other }
|
17
17
|
#
|
18
18
|
# it { does_something }
|
19
|
+
#
|
19
20
|
class EmptyLineAfterFinalLet < Base
|
20
21
|
extend AutoCorrector
|
21
22
|
include EmptyLineSeparation
|
22
23
|
|
23
24
|
MSG = 'Add an empty line after the last `%<let>s`.'
|
24
25
|
|
25
|
-
def on_block(node)
|
26
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
26
27
|
return unless example_group_with_body?(node)
|
27
28
|
|
28
29
|
final_let = node.body.child_nodes.reverse.find { |child| let?(child) }
|
@@ -5,6 +5,9 @@ module RuboCop
|
|
5
5
|
module RSpec
|
6
6
|
# Checks if there is an empty line after hook blocks.
|
7
7
|
#
|
8
|
+
# `AllowConsecutiveOneLiners` configures whether adjacent
|
9
|
+
# one-line definitions are considered an offense.
|
10
|
+
#
|
8
11
|
# @example
|
9
12
|
# # bad
|
10
13
|
# before { do_something }
|
@@ -19,11 +22,23 @@ module RuboCop
|
|
19
22
|
# it { does_something }
|
20
23
|
#
|
21
24
|
# # good
|
22
|
-
#
|
25
|
+
# after { do_something }
|
23
26
|
#
|
24
27
|
# it { does_something }
|
25
28
|
#
|
26
|
-
# #
|
29
|
+
# # fair - it's ok to have non-separated one-liners hooks
|
30
|
+
# around { |test| test.run }
|
31
|
+
# after { do_something }
|
32
|
+
#
|
33
|
+
# it { does_something }
|
34
|
+
#
|
35
|
+
# @example with AllowConsecutiveOneLiners configuration
|
36
|
+
# # rubocop.yml
|
37
|
+
# # RSpec/EmptyLineAfterHook:
|
38
|
+
# # AllowConsecutiveOneLiners: false
|
39
|
+
#
|
40
|
+
# # bad
|
41
|
+
# around { |test| test.run }
|
27
42
|
# after { do_something }
|
28
43
|
#
|
29
44
|
# it { does_something }
|
@@ -31,21 +46,36 @@ module RuboCop
|
|
31
46
|
# # good
|
32
47
|
# around { |test| test.run }
|
33
48
|
#
|
49
|
+
# after { do_something }
|
50
|
+
#
|
34
51
|
# it { does_something }
|
35
52
|
#
|
36
53
|
class EmptyLineAfterHook < Base
|
37
54
|
extend AutoCorrector
|
55
|
+
include ConfigurableEnforcedStyle
|
38
56
|
include EmptyLineSeparation
|
39
57
|
|
40
58
|
MSG = 'Add an empty line after `%<hook>s`.'
|
41
59
|
|
42
60
|
def on_block(node)
|
43
61
|
return unless hook?(node)
|
62
|
+
return if cop_config['AllowConsecutiveOneLiners'] &&
|
63
|
+
chained_single_line_hooks?(node)
|
44
64
|
|
45
65
|
missing_separating_line_offense(node) do |method|
|
46
66
|
format(MSG, hook: method)
|
47
67
|
end
|
48
68
|
end
|
69
|
+
|
70
|
+
alias on_numblock on_block
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def chained_single_line_hooks?(node)
|
75
|
+
next_node = node.right_sibling
|
76
|
+
|
77
|
+
hook?(next_node) && node.single_line? && next_node.single_line?
|
78
|
+
end
|
49
79
|
end
|
50
80
|
end
|
51
81
|
end
|
@@ -14,6 +14,7 @@ module RuboCop
|
|
14
14
|
# subject(:obj) { described_class }
|
15
15
|
#
|
16
16
|
# let(:foo) { bar }
|
17
|
+
#
|
17
18
|
class EmptyLineAfterSubject < Base
|
18
19
|
extend AutoCorrector
|
19
20
|
include EmptyLineSeparation
|
@@ -21,7 +22,7 @@ module RuboCop
|
|
21
22
|
|
22
23
|
MSG = 'Add an empty line after `%<subject>s`.'
|
23
24
|
|
24
|
-
def on_block(node)
|
25
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
25
26
|
return unless subject?(node)
|
26
27
|
return unless inside_example_group?(node)
|
27
28
|
|
@@ -47,12 +47,13 @@ module RuboCop
|
|
47
47
|
# content.
|
48
48
|
# HEREDOC
|
49
49
|
# end # 5 points
|
50
|
+
#
|
50
51
|
class ExampleLength < Base
|
51
52
|
include CodeLength
|
52
53
|
|
53
54
|
LABEL = 'Example'
|
54
55
|
|
55
|
-
def on_block(node)
|
56
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
56
57
|
return unless example?(node)
|
57
58
|
|
58
59
|
check_code_length(node)
|
@@ -47,6 +47,7 @@ module RuboCop
|
|
47
47
|
# result = service.call
|
48
48
|
# expect(result).to be(true)
|
49
49
|
# end
|
50
|
+
#
|
50
51
|
class ExampleWithoutDescription < Base
|
51
52
|
include ConfigurableEnforcedStyle
|
52
53
|
|
@@ -57,7 +58,7 @@ module RuboCop
|
|
57
58
|
# @!method example_description(node)
|
58
59
|
def_node_matcher :example_description, '(send nil? _ $(str $_))'
|
59
60
|
|
60
|
-
def on_block(node)
|
61
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
61
62
|
return unless example?(node)
|
62
63
|
|
63
64
|
check_example_without_description(node.send_node)
|
@@ -29,6 +29,7 @@ module RuboCop
|
|
29
29
|
# # good
|
30
30
|
# it 'does things' do
|
31
31
|
# end
|
32
|
+
#
|
32
33
|
class ExampleWording < Base
|
33
34
|
extend AutoCorrector
|
34
35
|
|
@@ -46,7 +47,7 @@ module RuboCop
|
|
46
47
|
} ...) ...)
|
47
48
|
PATTERN
|
48
49
|
|
49
|
-
def on_block(node)
|
50
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
50
51
|
it_description(node) do |description_node, message|
|
51
52
|
if message.match?(SHOULD_PREFIX)
|
52
53
|
add_wording_offense(description_node, MSG_SHOULD)
|
@@ -20,13 +20,14 @@ module RuboCop
|
|
20
20
|
# it do
|
21
21
|
# expect(something).to eq 'foo'
|
22
22
|
# end
|
23
|
+
#
|
23
24
|
class ExpectInHook < Base
|
24
25
|
MSG = 'Do not use `%<expect>s` in `%<hook>s` hook'
|
25
26
|
|
26
27
|
# @!method expectation(node)
|
27
28
|
def_node_search :expectation, send_pattern('#Expectations.all')
|
28
29
|
|
29
|
-
def on_block(node)
|
30
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
30
31
|
return unless hook?(node)
|
31
32
|
return if node.body.nil?
|
32
33
|
|
@@ -36,6 +37,8 @@ module RuboCop
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
40
|
+
alias on_numblock on_block
|
41
|
+
|
39
42
|
private
|
40
43
|
|
41
44
|
def message(expect, hook)
|
@@ -24,6 +24,7 @@ module RuboCop
|
|
24
24
|
#
|
25
25
|
# # good
|
26
26
|
# count { 1 }
|
27
|
+
#
|
27
28
|
class AttributeDefinedStatically < Base
|
28
29
|
extend AutoCorrector
|
29
30
|
|
@@ -39,7 +40,7 @@ module RuboCop
|
|
39
40
|
(block (send _ #attribute_defining_method? ...) _ { (begin $...) $(send ...) } )
|
40
41
|
PATTERN
|
41
42
|
|
42
|
-
def on_block(node)
|
43
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
43
44
|
attributes = factory_attributes(node) || []
|
44
45
|
attributes = [attributes] unless attributes.is_a?(Array) # rubocop:disable Style/ArrayCoercion, Lint/RedundantCopDisableDirective
|
45
46
|
|
@@ -30,6 +30,7 @@ module RuboCop
|
|
30
30
|
#
|
31
31
|
# # good
|
32
32
|
# 3.times { create :user }
|
33
|
+
#
|
33
34
|
class CreateList < Base
|
34
35
|
extend AutoCorrector
|
35
36
|
include ConfigurableEnforcedStyle
|
@@ -39,20 +40,23 @@ module RuboCop
|
|
39
40
|
MSG_N_TIMES = 'Prefer %<number>s.times.'
|
40
41
|
RESTRICT_ON_SEND = %i[create_list].freeze
|
41
42
|
|
42
|
-
# @!method
|
43
|
-
def_node_matcher :
|
43
|
+
# @!method array_new_or_n_times_block?(node)
|
44
|
+
def_node_matcher :array_new_or_n_times_block?, <<-PATTERN
|
44
45
|
(block
|
45
|
-
|
46
|
+
{
|
47
|
+
(send (const {nil? | cbase} :Array) :new (int _)) |
|
48
|
+
(send (int _) :times)
|
49
|
+
}
|
46
50
|
...
|
47
51
|
)
|
48
52
|
PATTERN
|
49
53
|
|
50
|
-
# @!method
|
51
|
-
def_node_matcher :
|
54
|
+
# @!method block_with_arg_and_used?(node)
|
55
|
+
def_node_matcher :block_with_arg_and_used?, <<-PATTERN
|
52
56
|
(block
|
53
|
-
|
57
|
+
_
|
54
58
|
(args (arg _value))
|
55
|
-
|
59
|
+
`_value
|
56
60
|
)
|
57
61
|
PATTERN
|
58
62
|
|
@@ -71,11 +75,11 @@ module RuboCop
|
|
71
75
|
(send {nil? #factory_bot?} :create_list (sym _) (int $_) ...)
|
72
76
|
PATTERN
|
73
77
|
|
74
|
-
def on_block(node)
|
78
|
+
def on_block(node) # rubocop:todo InternalAffairs/NumblockHandler
|
75
79
|
return unless style == :create_list
|
76
80
|
|
77
|
-
return unless
|
78
|
-
return if
|
81
|
+
return unless array_new_or_n_times_block?(node)
|
82
|
+
return if block_with_arg_and_used?(node)
|
79
83
|
return unless node.body
|
80
84
|
return if arguments_include_method_call?(node.body)
|
81
85
|
return unless contains_only_factory?(node.body)
|
@@ -183,7 +187,7 @@ module RuboCop
|
|
183
187
|
|
184
188
|
def call_with_block_replacement(node)
|
185
189
|
block = node.body
|
186
|
-
arguments = build_arguments(block, node
|
190
|
+
arguments = build_arguments(block, count_from(node))
|
187
191
|
replacement = format_receiver(block.receiver)
|
188
192
|
replacement += format_method_call(block, 'create_list', arguments)
|
189
193
|
replacement += format_block(block)
|
@@ -203,7 +207,7 @@ module RuboCop
|
|
203
207
|
block = node.body
|
204
208
|
factory, *options = *block.arguments
|
205
209
|
|
206
|
-
arguments = "#{factory.source}, #{node
|
210
|
+
arguments = "#{factory.source}, #{count_from(node)}"
|
207
211
|
options = build_options_string(options)
|
208
212
|
arguments += ", #{options}" unless options.empty?
|
209
213
|
|
@@ -212,6 +216,16 @@ module RuboCop
|
|
212
216
|
replacement
|
213
217
|
end
|
214
218
|
|
219
|
+
def count_from(node)
|
220
|
+
count_node =
|
221
|
+
if node.receiver.int_type?
|
222
|
+
node.receiver
|
223
|
+
else
|
224
|
+
node.send_node.first_argument
|
225
|
+
end
|
226
|
+
count_node.source
|
227
|
+
end
|
228
|
+
|
215
229
|
def format_block(node)
|
216
230
|
if node.body.begin_type?
|
217
231
|
format_multiline_block(node)
|
@@ -58,6 +58,7 @@ module RuboCop
|
|
58
58
|
#
|
59
59
|
class FilePath < Base
|
60
60
|
include TopLevelGroup
|
61
|
+
include Namespace
|
61
62
|
|
62
63
|
MSG = 'Spec path should end with `%<suffix>s`.'
|
63
64
|
|
@@ -101,7 +102,7 @@ module RuboCop
|
|
101
102
|
|
102
103
|
def pattern_for(example_group, method_name)
|
103
104
|
if spec_suffix_only? || !example_group.const_type?
|
104
|
-
return pattern_for_spec_suffix_only
|
105
|
+
return pattern_for_spec_suffix_only
|
105
106
|
end
|
106
107
|
|
107
108
|
[
|
@@ -111,7 +112,7 @@ module RuboCop
|
|
111
112
|
].join
|
112
113
|
end
|
113
114
|
|
114
|
-
def pattern_for_spec_suffix_only
|
115
|
+
def pattern_for_spec_suffix_only
|
115
116
|
'.*_spec\.rb'
|
116
117
|
end
|
117
118
|
|
@@ -123,8 +124,10 @@ module RuboCop
|
|
123
124
|
end
|
124
125
|
|
125
126
|
def expected_path(constant)
|
127
|
+
constants = namespace(constant) + constant.const_name.split('::')
|
128
|
+
|
126
129
|
File.join(
|
127
|
-
|
130
|
+
constants.map do |name|
|
128
131
|
custom_transform.fetch(name) { camel_to_snake_case(name) }
|
129
132
|
end
|
130
133
|
)
|
@@ -5,6 +5,8 @@ module RuboCop
|
|
5
5
|
module RSpec
|
6
6
|
# Checks if examples are focused.
|
7
7
|
#
|
8
|
+
# This cop does not support autocorrection in some cases.
|
9
|
+
#
|
8
10
|
# @example
|
9
11
|
# # bad
|
10
12
|
# describe MyClass, focus: true do
|
@@ -19,6 +21,22 @@ module RuboCop
|
|
19
21
|
# # good
|
20
22
|
# describe MyClass do
|
21
23
|
# end
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# fdescribe 'test' do; end
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# describe 'test' do; end
|
30
|
+
#
|
31
|
+
# # bad
|
32
|
+
# fdescribe 'test' do; end
|
33
|
+
#
|
34
|
+
# # good
|
35
|
+
# describe 'test' do; end
|
36
|
+
#
|
37
|
+
# # bad (does not support autocorrection)
|
38
|
+
# focus 'test' do; end
|
39
|
+
#
|
22
40
|
class Focus < Base
|
23
41
|
extend AutoCorrector
|
24
42
|
include RangeHelp
|
@@ -57,6 +57,7 @@ module RuboCop
|
|
57
57
|
# before(:example) do
|
58
58
|
# # ...
|
59
59
|
# end
|
60
|
+
#
|
60
61
|
class HookArgument < Base
|
61
62
|
extend AutoCorrector
|
62
63
|
include ConfigurableEnforcedStyle
|
@@ -66,11 +67,13 @@ module RuboCop
|
|
66
67
|
|
67
68
|
# @!method scoped_hook(node)
|
68
69
|
def_node_matcher :scoped_hook, <<-PATTERN
|
69
|
-
(block $(send _ #Hooks.all (sym ${:each :example})) ...)
|
70
|
+
({block numblock} $(send _ #Hooks.all (sym ${:each :example})) ...)
|
70
71
|
PATTERN
|
71
72
|
|
72
73
|
# @!method unscoped_hook(node)
|
73
|
-
def_node_matcher :unscoped_hook,
|
74
|
+
def_node_matcher :unscoped_hook, <<-PATTERN
|
75
|
+
({block numblock} $(send _ #Hooks.all) ...)
|
76
|
+
PATTERN
|
74
77
|
|
75
78
|
def on_block(node)
|
76
79
|
hook(node) do |method_send, scope_name|
|
@@ -86,6 +89,8 @@ module RuboCop
|
|
86
89
|
end
|
87
90
|
end
|
88
91
|
|
92
|
+
alias on_numblock on_block
|
93
|
+
|
89
94
|
private
|
90
95
|
|
91
96
|
def check_implicit(method_send)
|
@@ -6,8 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks for before/around/after hooks that come after an example.
|
7
7
|
#
|
8
8
|
# @example
|
9
|
-
# #
|
10
|
-
#
|
9
|
+
# # bad
|
11
10
|
# it 'checks what foo does' do
|
12
11
|
# expect(foo).to be
|
13
12
|
# end
|
@@ -15,7 +14,7 @@ module RuboCop
|
|
15
14
|
# before { prepare }
|
16
15
|
# after { clean_up }
|
17
16
|
#
|
18
|
-
# #
|
17
|
+
# # good
|
19
18
|
# before { prepare }
|
20
19
|
# after { clean_up }
|
21
20
|
#
|
@@ -32,6 +31,7 @@ module RuboCop
|
|
32
31
|
def_node_matcher :example_or_group?, <<-PATTERN
|
33
32
|
{
|
34
33
|
#{block_pattern('{#ExampleGroups.all #Examples.all}')}
|
34
|
+
#{numblock_pattern('{#ExampleGroups.all #Examples.all}')}
|
35
35
|
#{send_pattern('#Includes.examples')}
|
36
36
|
}
|
37
37
|
PATTERN
|
@@ -42,6 +42,8 @@ module RuboCop
|
|
42
42
|
check_hooks(node.body) if multiline_block?(node.body)
|
43
43
|
end
|
44
44
|
|
45
|
+
alias on_numblock on_block
|
46
|
+
|
45
47
|
private
|
46
48
|
|
47
49
|
def multiline_block?(block)
|
@@ -52,13 +54,12 @@ module RuboCop
|
|
52
54
|
first_example = find_first_example(node)
|
53
55
|
return unless first_example
|
54
56
|
|
55
|
-
|
56
|
-
next
|
57
|
-
next unless hook?(child)
|
57
|
+
first_example.right_siblings.each do |sibling|
|
58
|
+
next unless hook?(sibling)
|
58
59
|
|
59
|
-
msg = format(MSG, hook:
|
60
|
-
add_offense(
|
61
|
-
autocorrect(corrector,
|
60
|
+
msg = format(MSG, hook: sibling.method_name)
|
61
|
+
add_offense(sibling, message: msg) do |corrector|
|
62
|
+
autocorrect(corrector, sibling, first_example)
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
@@ -16,6 +16,7 @@ module RuboCop
|
|
16
16
|
# it 'changes something to a new value' do
|
17
17
|
# expect { do_something }.to change(something).to(new_value)
|
18
18
|
# end
|
19
|
+
#
|
19
20
|
class ImplicitBlockExpectation < Base
|
20
21
|
MSG = 'Avoid implicit block expectations.'
|
21
22
|
RESTRICT_ON_SEND = %i[is_expected should should_not].freeze
|
@@ -9,7 +9,6 @@ module RuboCop
|
|
9
9
|
# and supports the `--auto-gen-config` flag.
|
10
10
|
#
|
11
11
|
# @example `EnforcedStyle: is_expected` (default)
|
12
|
-
#
|
13
12
|
# # bad
|
14
13
|
# it { should be_truthy }
|
15
14
|
#
|
@@ -17,7 +16,6 @@ module RuboCop
|
|
17
16
|
# it { is_expected.to be_truthy }
|
18
17
|
#
|
19
18
|
# @example `EnforcedStyle: should`
|
20
|
-
#
|
21
19
|
# # bad
|
22
20
|
# it { is_expected.to be_truthy }
|
23
21
|
#
|