rubocop-rspec 2.2.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -0
- data/README.md +3 -5
- data/config/default.yml +79 -3
- data/lib/rubocop/cop/rspec/around_block.rb +2 -0
- data/lib/rubocop/cop/rspec/be.rb +1 -0
- data/lib/rubocop/cop/rspec/be_eql.rb +1 -0
- data/lib/rubocop/cop/rspec/before_after_all.rb +1 -0
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +3 -0
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +3 -0
- data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +2 -0
- data/lib/rubocop/cop/rspec/context_method.rb +1 -0
- data/lib/rubocop/cop/rspec/context_wording.rb +7 -1
- data/lib/rubocop/cop/rspec/describe_class.rb +3 -0
- data/lib/rubocop/cop/rspec/describe_method.rb +1 -0
- data/lib/rubocop/cop/rspec/describe_symbol.rb +1 -0
- data/lib/rubocop/cop/rspec/described_class.rb +6 -1
- data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +2 -1
- data/lib/rubocop/cop/rspec/dialect.rb +1 -0
- data/lib/rubocop/cop/rspec/empty_hook.rb +5 -1
- data/lib/rubocop/cop/rspec/example_length.rb +26 -12
- data/lib/rubocop/cop/rspec/example_without_description.rb +1 -0
- data/lib/rubocop/cop/rspec/example_wording.rb +4 -0
- data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +100 -0
- data/lib/rubocop/cop/rspec/expect_actual.rb +1 -0
- data/lib/rubocop/cop/rspec/expect_change.rb +5 -3
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -0
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +3 -0
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +3 -0
- data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -0
- data/lib/rubocop/cop/rspec/file_path.rb +13 -9
- data/lib/rubocop/cop/rspec/focus.rb +3 -0
- data/lib/rubocop/cop/rspec/hook_argument.rb +3 -1
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +1 -0
- data/lib/rubocop/cop/rspec/identical_equality_assertion.rb +38 -0
- data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +3 -0
- data/lib/rubocop/cop/rspec/implicit_expect.rb +1 -0
- data/lib/rubocop/cop/rspec/implicit_subject.rb +18 -1
- data/lib/rubocop/cop/rspec/instance_spy.rb +2 -0
- data/lib/rubocop/cop/rspec/instance_variable.rb +4 -0
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +1 -0
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +4 -0
- data/lib/rubocop/cop/rspec/let_before_examples.rb +1 -0
- data/lib/rubocop/cop/rspec/let_setup.rb +3 -0
- data/lib/rubocop/cop/rspec/message_expectation.rb +2 -0
- data/lib/rubocop/cop/rspec/message_spies.rb +2 -0
- data/lib/rubocop/cop/rspec/mixin/variable.rb +1 -0
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +3 -0
- data/lib/rubocop/cop/rspec/named_subject.rb +3 -0
- data/lib/rubocop/cop/rspec/nested_groups.rb +1 -1
- data/lib/rubocop/cop/rspec/not_to_not.rb +1 -0
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +2 -0
- data/lib/rubocop/cop/rspec/pending.rb +4 -0
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +5 -0
- data/lib/rubocop/cop/rspec/rails/avoid_setup_hook.rb +44 -0
- data/lib/rubocop/cop/rspec/rails/http_status.rb +1 -0
- data/lib/rubocop/cop/rspec/receive_counts.rb +2 -0
- data/lib/rubocop/cop/rspec/receive_never.rb +1 -0
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +8 -1
- data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +4 -0
- data/lib/rubocop/cop/rspec/repeated_include_example.rb +3 -0
- data/lib/rubocop/cop/rspec/return_from_stub.rb +5 -0
- data/lib/rubocop/cop/rspec/shared_context.rb +4 -0
- data/lib/rubocop/cop/rspec/shared_examples.rb +1 -0
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +2 -0
- data/lib/rubocop/cop/rspec/stubbed_mock.rb +1 -0
- data/lib/rubocop/cop/rspec/subject_declaration.rb +47 -0
- data/lib/rubocop/cop/rspec/subject_stub.rb +1 -0
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -0
- data/lib/rubocop/cop/rspec/variable_definition.rb +19 -2
- data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -0
- data/lib/rubocop/cop/rspec/void_expect.rb +2 -0
- data/lib/rubocop/cop/rspec/yield.rb +3 -0
- data/lib/rubocop/cop/rspec_cops.rb +4 -0
- data/lib/rubocop/rspec/align_let_brace.rb +2 -1
- data/lib/rubocop/rspec/config_formatter.rb +3 -0
- data/lib/rubocop/rspec/example.rb +5 -0
- data/lib/rubocop/rspec/hook.rb +1 -0
- data/lib/rubocop/rspec/language.rb +10 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +17 -27
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks for excessive whitespace in example descriptions.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# it ' has excessive spacing ' do
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# it 'has excessive spacing' do
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# # bad
|
19
|
+
# context ' when a condition is met ' do
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# context 'when a condition is met' do
|
24
|
+
# end
|
25
|
+
class ExcessiveDocstringSpacing < Base
|
26
|
+
extend AutoCorrector
|
27
|
+
|
28
|
+
MSG = 'Excessive whitespace.'
|
29
|
+
|
30
|
+
# @!method example_description(node)
|
31
|
+
def_node_matcher :example_description, <<-PATTERN
|
32
|
+
(send _ {#Examples.all #ExampleGroups.all} ${
|
33
|
+
$str
|
34
|
+
$(dstr ({str dstr `sym} ...) ...)
|
35
|
+
} ...)
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def on_send(node)
|
39
|
+
example_description(node) do |description_node, message|
|
40
|
+
return if description_node.heredoc?
|
41
|
+
|
42
|
+
text = text(message)
|
43
|
+
|
44
|
+
return unless excessive_whitespace?(text)
|
45
|
+
|
46
|
+
add_whitespace_offense(description_node, text)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# @param text [String]
|
53
|
+
def excessive_whitespace?(text)
|
54
|
+
return true if text.start_with?(' ') || text.end_with?(' ')
|
55
|
+
|
56
|
+
text.match?(/[^\n ] +[^ ]/)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @param text [String]
|
60
|
+
def strip_excessive_whitespace(text)
|
61
|
+
text.strip.gsub(/ +/, ' ')
|
62
|
+
end
|
63
|
+
|
64
|
+
# @param node [RuboCop::AST::Node]
|
65
|
+
# @param text [String]
|
66
|
+
def add_whitespace_offense(node, text)
|
67
|
+
docstring = docstring(node)
|
68
|
+
corrected = strip_excessive_whitespace(text)
|
69
|
+
|
70
|
+
add_offense(docstring) do |corrector|
|
71
|
+
corrector.replace(docstring, corrected)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def docstring(node)
|
76
|
+
expr = node.loc.expression
|
77
|
+
|
78
|
+
Parser::Source::Range.new(
|
79
|
+
expr.source_buffer,
|
80
|
+
expr.begin_pos + 1,
|
81
|
+
expr.end_pos - 1
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Recursive processing is required to process nested dstr nodes
|
86
|
+
# that is the case for \-separated multiline strings with interpolation.
|
87
|
+
def text(node)
|
88
|
+
case node.type
|
89
|
+
when :dstr
|
90
|
+
node.node_parts.map { |child_node| text(child_node) }.join
|
91
|
+
when :str, :sym
|
92
|
+
node.value
|
93
|
+
when :begin
|
94
|
+
node.source
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -37,10 +37,12 @@ module RuboCop
|
|
37
37
|
MSG_CALL = 'Prefer `change { %<obj>s.%<attr>s }`.'
|
38
38
|
RESTRICT_ON_SEND = %i[change].freeze
|
39
39
|
|
40
|
+
# @!method expect_change_with_arguments(node)
|
40
41
|
def_node_matcher :expect_change_with_arguments, <<-PATTERN
|
41
|
-
(send nil? :change
|
42
|
+
(send nil? :change $_ (sym $_))
|
42
43
|
PATTERN
|
43
44
|
|
45
|
+
# @!method expect_change_with_block(node)
|
44
46
|
def_node_matcher :expect_change_with_block, <<-PATTERN
|
45
47
|
(block
|
46
48
|
(send nil? :change)
|
@@ -53,9 +55,9 @@ module RuboCop
|
|
53
55
|
return unless style == :block
|
54
56
|
|
55
57
|
expect_change_with_arguments(node) do |receiver, message|
|
56
|
-
msg = format(MSG_CALL, obj: receiver, attr: message)
|
58
|
+
msg = format(MSG_CALL, obj: receiver.source, attr: message)
|
57
59
|
add_offense(node, message: msg) do |corrector|
|
58
|
-
replacement = "change { #{receiver}.#{message} }"
|
60
|
+
replacement = "change { #{receiver.source}.#{message} }"
|
59
61
|
corrector.replace(node, replacement)
|
60
62
|
end
|
61
63
|
end
|
@@ -29,10 +29,12 @@ module RuboCop
|
|
29
29
|
|
30
30
|
MSG = 'Use a block to declare attribute values.'
|
31
31
|
|
32
|
+
# @!method value_matcher(node)
|
32
33
|
def_node_matcher :value_matcher, <<-PATTERN
|
33
34
|
(send _ !#reserved_method? $...)
|
34
35
|
PATTERN
|
35
36
|
|
37
|
+
# @!method factory_attributes(node)
|
36
38
|
def_node_matcher :factory_attributes, <<-PATTERN
|
37
39
|
(block (send _ #attribute_defining_method? ...) _ { (begin $...) $(send ...) } )
|
38
40
|
PATTERN
|
@@ -79,6 +81,7 @@ module RuboCop
|
|
79
81
|
value_matcher(attribute).to_a.all?(&:block_pass_type?)
|
80
82
|
end
|
81
83
|
|
84
|
+
# @!method association?(node)
|
82
85
|
def_node_matcher :association?, '(hash <(pair (sym :factory) _) ...>)'
|
83
86
|
|
84
87
|
def autocorrect_replacing_parens(corrector, node)
|
@@ -32,6 +32,7 @@ module RuboCop
|
|
32
32
|
MSG_N_TIMES = 'Prefer %<number>s.times.'
|
33
33
|
RESTRICT_ON_SEND = %i[create_list].freeze
|
34
34
|
|
35
|
+
# @!method n_times_block_without_arg?(node)
|
35
36
|
def_node_matcher :n_times_block_without_arg?, <<-PATTERN
|
36
37
|
(block
|
37
38
|
(send (int _) :times)
|
@@ -40,10 +41,12 @@ module RuboCop
|
|
40
41
|
)
|
41
42
|
PATTERN
|
42
43
|
|
44
|
+
# @!method factory_call(node)
|
43
45
|
def_node_matcher :factory_call, <<-PATTERN
|
44
46
|
(send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create (sym $_) $...)
|
45
47
|
PATTERN
|
46
48
|
|
49
|
+
# @!method factory_list_call(node)
|
47
50
|
def_node_matcher :factory_list_call, <<-PATTERN
|
48
51
|
(send {(const nil? {:FactoryGirl :FactoryBot}) nil?} :create_list (sym _) (int $_) ...)
|
49
52
|
PATTERN
|
@@ -27,6 +27,7 @@ module RuboCop
|
|
27
27
|
ALLOWED_CONSTANTS = %w[Hash OpenStruct].freeze
|
28
28
|
RESTRICT_ON_SEND = %i[factory].freeze
|
29
29
|
|
30
|
+
# @!method class_name(node)
|
30
31
|
def_node_matcher :class_name, <<~PATTERN
|
31
32
|
(send _ :factory _ (hash <(pair (sym :class) $(const ...)) ...>))
|
32
33
|
PATTERN
|
@@ -61,28 +61,30 @@ module RuboCop
|
|
61
61
|
|
62
62
|
MSG = 'Spec path should end with `%<suffix>s`.'
|
63
63
|
|
64
|
-
|
64
|
+
# @!method example_group(node)
|
65
|
+
def_node_matcher :example_group, <<~PATTERN
|
65
66
|
(block
|
66
|
-
$(send #rspec? _example_group $
|
67
|
+
$(send #rspec? _example_group $_ $...) ...
|
67
68
|
)
|
68
69
|
PATTERN
|
69
70
|
|
71
|
+
# @!method routing_metadata?(node)
|
70
72
|
def_node_search :routing_metadata?, '(pair (sym :type) (sym :routing))'
|
71
73
|
|
72
74
|
def on_top_level_example_group(node)
|
73
75
|
return unless top_level_groups.one?
|
74
76
|
|
75
|
-
|
77
|
+
example_group(node) do |send_node, example_group, arguments|
|
76
78
|
next if routing_spec?(arguments)
|
77
79
|
|
78
|
-
ensure_correct_file_path(send_node,
|
80
|
+
ensure_correct_file_path(send_node, example_group, arguments)
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
82
84
|
private
|
83
85
|
|
84
|
-
def ensure_correct_file_path(send_node,
|
85
|
-
pattern = pattern_for(
|
86
|
+
def ensure_correct_file_path(send_node, example_group, arguments)
|
87
|
+
pattern = pattern_for(example_group, arguments.first)
|
86
88
|
return if filename_ends_with?(pattern)
|
87
89
|
|
88
90
|
# For the suffix shown in the offense message, modify the regular
|
@@ -97,11 +99,13 @@ module RuboCop
|
|
97
99
|
args.any?(&method(:routing_metadata?))
|
98
100
|
end
|
99
101
|
|
100
|
-
def pattern_for(
|
101
|
-
|
102
|
+
def pattern_for(example_group, method_name)
|
103
|
+
if spec_suffix_only? || !example_group.const_type?
|
104
|
+
return pattern_for_spec_suffix_only?
|
105
|
+
end
|
102
106
|
|
103
107
|
[
|
104
|
-
expected_path(
|
108
|
+
expected_path(example_group),
|
105
109
|
name_pattern(method_name),
|
106
110
|
'[^/]*_spec\.rb'
|
107
111
|
].join
|
@@ -25,6 +25,7 @@ module RuboCop
|
|
25
25
|
|
26
26
|
MSG = 'Focused spec found.'
|
27
27
|
|
28
|
+
# @!method focusable_selector?(node)
|
28
29
|
def_node_matcher :focusable_selector?, <<-PATTERN
|
29
30
|
{
|
30
31
|
#ExampleGroups.regular
|
@@ -35,11 +36,13 @@ module RuboCop
|
|
35
36
|
}
|
36
37
|
PATTERN
|
37
38
|
|
39
|
+
# @!method metadata(node)
|
38
40
|
def_node_matcher :metadata, <<-PATTERN
|
39
41
|
{(send #rspec? #focusable_selector? <$(sym :focus) ...>)
|
40
42
|
(send #rspec? #focusable_selector? ... (hash <$(pair (sym :focus) true) ...>))}
|
41
43
|
PATTERN
|
42
44
|
|
45
|
+
# @!method focused_block?(node)
|
43
46
|
def_node_matcher :focused_block?,
|
44
47
|
send_pattern(<<~PATTERN)
|
45
48
|
{#ExampleGroups.focused #Examples.focused}
|
@@ -32,7 +32,7 @@ module RuboCop
|
|
32
32
|
# # ...
|
33
33
|
# end
|
34
34
|
#
|
35
|
-
# #
|
35
|
+
# # bad
|
36
36
|
# before do
|
37
37
|
# # ...
|
38
38
|
# end
|
@@ -64,10 +64,12 @@ module RuboCop
|
|
64
64
|
IMPLICIT_MSG = 'Omit the default `%<scope>p` argument for RSpec hooks.'
|
65
65
|
EXPLICIT_MSG = 'Use `%<scope>p` for RSpec hooks.'
|
66
66
|
|
67
|
+
# @!method scoped_hook(node)
|
67
68
|
def_node_matcher :scoped_hook, <<-PATTERN
|
68
69
|
(block $(send _ #Hooks.all (sym ${:each :example})) ...)
|
69
70
|
PATTERN
|
70
71
|
|
72
|
+
# @!method unscoped_hook(node)
|
71
73
|
def_node_matcher :unscoped_hook, '(block $(send _ #Hooks.all) ...)'
|
72
74
|
|
73
75
|
def on_block(node)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks for equality assertions with identical expressions on both sides.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# expect(foo.bar).to eq(foo.bar)
|
12
|
+
# expect(foo.bar).to eql(foo.bar)
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# expect(foo.bar).to eq(2)
|
16
|
+
# expect(foo.bar).to eql(2)
|
17
|
+
#
|
18
|
+
class IdenticalEqualityAssertion < Base
|
19
|
+
MSG = 'Identical expressions on both sides of the equality ' \
|
20
|
+
'may indicate a flawed test.'
|
21
|
+
RESTRICT_ON_SEND = %i[to].freeze
|
22
|
+
|
23
|
+
# @!method equality_check?(node)
|
24
|
+
def_node_matcher :equality_check?, <<~PATTERN
|
25
|
+
(send (send nil? :expect $_) :to
|
26
|
+
{(send nil? {:eql :eq :be} $_)
|
27
|
+
(send (send nil? :be) :== $_)})
|
28
|
+
PATTERN
|
29
|
+
|
30
|
+
def on_send(node)
|
31
|
+
equality_check?(node) do |left, right|
|
32
|
+
add_offense(node) if left == right
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -20,6 +20,7 @@ module RuboCop
|
|
20
20
|
MSG = 'Avoid implicit block expectations.'
|
21
21
|
RESTRICT_ON_SEND = %i[is_expected should should_not].freeze
|
22
22
|
|
23
|
+
# @!method lambda?(node)
|
23
24
|
def_node_matcher :lambda?, <<-PATTERN
|
24
25
|
{
|
25
26
|
(send (const nil? :Proc) :new)
|
@@ -27,8 +28,10 @@ module RuboCop
|
|
27
28
|
}
|
28
29
|
PATTERN
|
29
30
|
|
31
|
+
# @!method lambda_subject?(node)
|
30
32
|
def_node_matcher :lambda_subject?, '(block #lambda? ...)'
|
31
33
|
|
34
|
+
# @!method implicit_expect(node)
|
32
35
|
def_node_matcher :implicit_expect, <<-PATTERN
|
33
36
|
$(send nil? {:is_expected :should :should_not} ...)
|
34
37
|
PATTERN
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# This cop can be configured using the `EnforcedStyle` option
|
9
9
|
#
|
10
|
-
# @example `EnforcedStyle: single_line_only`
|
10
|
+
# @example `EnforcedStyle: single_line_only` (default)
|
11
11
|
# # bad
|
12
12
|
# it do
|
13
13
|
# is_expected.to be_truthy
|
@@ -19,6 +19,22 @@ module RuboCop
|
|
19
19
|
# expect(subject).to be_truthy
|
20
20
|
# end
|
21
21
|
#
|
22
|
+
# @example `EnforcedStyle: single_statement_only`
|
23
|
+
# # bad
|
24
|
+
# it do
|
25
|
+
# foo = 1
|
26
|
+
# is_expected.to be_truthy
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# it do
|
31
|
+
# foo = 1
|
32
|
+
# expect(subject).to be_truthy
|
33
|
+
# end
|
34
|
+
# it do
|
35
|
+
# is_expected.to be_truthy
|
36
|
+
# end
|
37
|
+
#
|
22
38
|
# @example `EnforcedStyle: disallow`
|
23
39
|
# # bad
|
24
40
|
# it { is_expected.to be_truthy }
|
@@ -33,6 +49,7 @@ module RuboCop
|
|
33
49
|
MSG = "Don't use implicit subject."
|
34
50
|
RESTRICT_ON_SEND = %i[is_expected should should_not].freeze
|
35
51
|
|
52
|
+
# @!method implicit_subject?(node)
|
36
53
|
def_node_matcher :implicit_subject?, <<-PATTERN
|
37
54
|
(send nil? {:should :should_not :is_expected} ...)
|
38
55
|
PATTERN
|
@@ -24,6 +24,7 @@ module RuboCop
|
|
24
24
|
MSG = 'Use `instance_spy` when you check your double ' \
|
25
25
|
'with `have_received`.'
|
26
26
|
|
27
|
+
# @!method null_double(node)
|
27
28
|
def_node_search :null_double, <<-PATTERN
|
28
29
|
(lvasgn $_
|
29
30
|
(send
|
@@ -31,6 +32,7 @@ module RuboCop
|
|
31
32
|
...) :as_null_object))
|
32
33
|
PATTERN
|
33
34
|
|
35
|
+
# @!method have_received_usage(node)
|
34
36
|
def_node_search :have_received_usage, <<-PATTERN
|
35
37
|
(send
|
36
38
|
(send nil? :expect
|
@@ -52,10 +52,12 @@ module RuboCop
|
|
52
52
|
MSG = 'Avoid instance variables – use let, ' \
|
53
53
|
'a method call, or a local variable (if possible).'
|
54
54
|
|
55
|
+
# @!method dynamic_class?(node)
|
55
56
|
def_node_matcher :dynamic_class?, <<-PATTERN
|
56
57
|
(block (send (const nil? :Class) :new ...) ...)
|
57
58
|
PATTERN
|
58
59
|
|
60
|
+
# @!method custom_matcher?(node)
|
59
61
|
def_node_matcher :custom_matcher?, <<-PATTERN
|
60
62
|
(block {
|
61
63
|
(send nil? :matcher sym)
|
@@ -63,8 +65,10 @@ module RuboCop
|
|
63
65
|
} ...)
|
64
66
|
PATTERN
|
65
67
|
|
68
|
+
# @!method ivar_usage(node)
|
66
69
|
def_node_search :ivar_usage, '$(ivar $_)'
|
67
70
|
|
71
|
+
# @!method ivar_assigned?(node)
|
68
72
|
def_node_search :ivar_assigned?, '(ivasgn % ...)'
|
69
73
|
|
70
74
|
def on_top_level_group(node)
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
19
19
|
MSG = 'Prefer using the `all` matcher instead ' \
|
20
20
|
'of iterating over an array.'
|
21
21
|
|
22
|
+
# @!method each?(node)
|
22
23
|
def_node_matcher :each?, <<-PATTERN
|
23
24
|
(block
|
24
25
|
(send ... :each)
|
@@ -27,6 +28,7 @@ module RuboCop
|
|
27
28
|
)
|
28
29
|
PATTERN
|
29
30
|
|
31
|
+
# @!method expectation?(node)
|
30
32
|
def_node_matcher :expectation?, <<-PATTERN
|
31
33
|
(send (send nil? :expect (lvar %)) :to ...)
|
32
34
|
PATTERN
|
@@ -46,6 +48,8 @@ module RuboCop
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def only_expectations?(body, arg)
|
51
|
+
return false unless body.each_child_node.any?
|
52
|
+
|
49
53
|
body.each_child_node.all? { |child| expectation?(child, arg) }
|
50
54
|
end
|
51
55
|
end
|
@@ -28,6 +28,7 @@ module RuboCop
|
|
28
28
|
class LetSetup < Base
|
29
29
|
MSG = 'Do not use `let!` to setup objects not referenced in tests.'
|
30
30
|
|
31
|
+
# @!method example_or_shared_group_or_including?(node)
|
31
32
|
def_node_matcher :example_or_shared_group_or_including?,
|
32
33
|
block_pattern(<<~PATTERN)
|
33
34
|
{
|
@@ -37,6 +38,7 @@ module RuboCop
|
|
37
38
|
}
|
38
39
|
PATTERN
|
39
40
|
|
41
|
+
# @!method let_bang(node)
|
40
42
|
def_node_matcher :let_bang, <<-PATTERN
|
41
43
|
{
|
42
44
|
(block $(send nil? :let! {(sym $_) (str $_)}) ...)
|
@@ -44,6 +46,7 @@ module RuboCop
|
|
44
46
|
}
|
45
47
|
PATTERN
|
46
48
|
|
49
|
+
# @!method method_called?(node)
|
47
50
|
def_node_search :method_called?, '(send nil? %)'
|
48
51
|
|
49
52
|
def on_block(node)
|
@@ -32,10 +32,12 @@ module RuboCop
|
|
32
32
|
SUPPORTED_STYLES = %w[allow expect].freeze
|
33
33
|
RESTRICT_ON_SEND = %i[to].freeze
|
34
34
|
|
35
|
+
# @!method message_expectation(node)
|
35
36
|
def_node_matcher :message_expectation, <<-PATTERN
|
36
37
|
(send $(send nil? {:expect :allow} ...) :to #receive_message?)
|
37
38
|
PATTERN
|
38
39
|
|
40
|
+
# @!method receive_message?(node)
|
39
41
|
def_node_search :receive_message?, '(send nil? :receive ...)'
|
40
42
|
|
41
43
|
def on_send(node)
|
@@ -35,10 +35,12 @@ module RuboCop
|
|
35
35
|
|
36
36
|
SUPPORTED_STYLES = %w[have_received receive].freeze
|
37
37
|
|
38
|
+
# @!method message_expectation(node)
|
38
39
|
def_node_matcher :message_expectation, %(
|
39
40
|
(send (send nil? :expect $_) #Runners.all ...)
|
40
41
|
)
|
41
42
|
|
43
|
+
# @!method receive_message(node)
|
42
44
|
def_node_search :receive_message, %(
|
43
45
|
$(send nil? {:receive :have_received} ...)
|
44
46
|
)
|
@@ -10,6 +10,7 @@ module RuboCop
|
|
10
10
|
Subjects = RuboCop::RSpec::Language::Subjects
|
11
11
|
Helpers = RuboCop::RSpec::Language::Helpers
|
12
12
|
|
13
|
+
# @!method variable_definition?(node)
|
13
14
|
def_node_matcher :variable_definition?, <<~PATTERN
|
14
15
|
(send nil? {#Subjects.all #Helpers.all}
|
15
16
|
$({sym str dsym dstr} ...) ...)
|
@@ -53,6 +53,7 @@ module RuboCop
|
|
53
53
|
ANYTHING = ->(_node) { true }
|
54
54
|
TRUE = ->(node) { node.true_type? }
|
55
55
|
|
56
|
+
# @!method aggregate_failures?(node)
|
56
57
|
def_node_matcher :aggregate_failures?, <<-PATTERN
|
57
58
|
(block {
|
58
59
|
(send _ _ <(sym :aggregate_failures) ...>)
|
@@ -60,7 +61,9 @@ module RuboCop
|
|
60
61
|
} ...)
|
61
62
|
PATTERN
|
62
63
|
|
64
|
+
# @!method expect?(node)
|
63
65
|
def_node_matcher :expect?, send_pattern('#Expectations.all')
|
66
|
+
# @!method aggregate_failures_block?(node)
|
64
67
|
def_node_matcher :aggregate_failures_block?, <<-PATTERN
|
65
68
|
(block (send nil? :aggregate_failures ...) ...)
|
66
69
|
PATTERN
|
@@ -44,12 +44,15 @@ module RuboCop
|
|
44
44
|
class NamedSubject < Base
|
45
45
|
MSG = 'Name your test subject if you need to reference it explicitly.'
|
46
46
|
|
47
|
+
# @!method example_or_hook_block?(node)
|
47
48
|
def_node_matcher :example_or_hook_block?,
|
48
49
|
block_pattern('{#Examples.all #Hooks.all}')
|
49
50
|
|
51
|
+
# @!method shared_example?(node)
|
50
52
|
def_node_matcher :shared_example?,
|
51
53
|
block_pattern('#SharedGroups.examples')
|
52
54
|
|
55
|
+
# @!method subject_usage(node)
|
53
56
|
def_node_search :subject_usage, '$(send nil? :subject)'
|
54
57
|
|
55
58
|
def on_block(node)
|
@@ -24,8 +24,10 @@ module RuboCop
|
|
24
24
|
class OverwritingSetup < Base
|
25
25
|
MSG = '`%<name>s` is already defined.'
|
26
26
|
|
27
|
+
# @!method setup?(node)
|
27
28
|
def_node_matcher :setup?, block_pattern('{#Helpers.all #Subjects.all}')
|
28
29
|
|
30
|
+
# @!method first_argument_name(node)
|
29
31
|
def_node_matcher :first_argument_name, '(send _ _ ({str sym} $_))'
|
30
32
|
|
31
33
|
def on_block(node)
|
@@ -34,11 +34,13 @@ module RuboCop
|
|
34
34
|
class Pending < Base
|
35
35
|
MSG = 'Pending spec found.'
|
36
36
|
|
37
|
+
# @!method skippable?(node)
|
37
38
|
def_node_matcher :skippable?,
|
38
39
|
send_pattern(<<~PATTERN)
|
39
40
|
{#ExampleGroups.regular #Examples.regular}
|
40
41
|
PATTERN
|
41
42
|
|
43
|
+
# @!method skipped_in_metadata?(node)
|
42
44
|
def_node_matcher :skipped_in_metadata?, <<-PATTERN
|
43
45
|
{
|
44
46
|
(send _ _ <#skip_or_pending? ...>)
|
@@ -46,8 +48,10 @@ module RuboCop
|
|
46
48
|
}
|
47
49
|
PATTERN
|
48
50
|
|
51
|
+
# @!method skip_or_pending?(node)
|
49
52
|
def_node_matcher :skip_or_pending?, '{(sym :skip) (sym :pending)}'
|
50
53
|
|
54
|
+
# @!method pending_block?(node)
|
51
55
|
def_node_matcher :pending_block?,
|
52
56
|
send_pattern(<<~PATTERN)
|
53
57
|
{
|