rubocop-rspec 1.38.1 → 1.43.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 +57 -0
- data/CODE_OF_CONDUCT.md +17 -0
- data/README.md +1 -61
- data/config/default.yml +159 -19
- data/lib/rubocop-rspec.rb +5 -2
- data/lib/rubocop/cop/rspec/align_left_let_brace.rb +12 -19
- data/lib/rubocop/cop/rspec/align_right_let_brace.rb +12 -19
- data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
- data/lib/rubocop/cop/rspec/around_block.rb +1 -1
- data/lib/rubocop/cop/rspec/base.rb +74 -0
- data/lib/rubocop/cop/rspec/be.rb +2 -2
- data/lib/rubocop/cop/rspec/be_eql.rb +6 -6
- data/lib/rubocop/cop/rspec/before_after_all.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +19 -17
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +14 -12
- data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +69 -0
- data/lib/rubocop/cop/rspec/context_method.rb +7 -9
- data/lib/rubocop/cop/rspec/context_wording.rb +3 -3
- data/lib/rubocop/cop/rspec/cop.rb +3 -87
- data/lib/rubocop/cop/rspec/describe_class.rb +29 -23
- data/lib/rubocop/cop/rspec/describe_method.rb +14 -7
- data/lib/rubocop/cop/rspec/describe_symbol.rb +2 -2
- data/lib/rubocop/cop/rspec/described_class.rb +12 -9
- data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
- data/lib/rubocop/cop/rspec/dialect.rb +5 -12
- data/lib/rubocop/cop/rspec/empty_example_group.rb +91 -7
- data/lib/rubocop/cop/rspec/empty_hook.rb +46 -0
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +5 -7
- data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +5 -9
- data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +8 -8
- data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +5 -9
- data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +6 -6
- 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 +10 -11
- data/lib/rubocop/cop/rspec/expect_actual.rb +8 -11
- data/lib/rubocop/cop/rspec/expect_change.rb +10 -35
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +3 -3
- data/lib/rubocop/cop/rspec/expect_output.rb +2 -2
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +24 -21
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +20 -22
- data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +7 -8
- data/lib/rubocop/cop/rspec/file_path.rb +57 -21
- data/lib/rubocop/cop/rspec/focus.rb +7 -11
- data/lib/rubocop/cop/rspec/hook_argument.rb +16 -23
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +10 -29
- data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/implicit_expect.rb +7 -15
- data/lib/rubocop/cop/rspec/implicit_subject.rb +16 -11
- data/lib/rubocop/cop/rspec/instance_spy.rb +18 -12
- data/lib/rubocop/cop/rspec/instance_variable.rb +4 -8
- data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +3 -6
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +5 -6
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/leading_subject.rb +22 -26
- data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +2 -5
- data/lib/rubocop/cop/rspec/let_before_examples.rb +10 -26
- data/lib/rubocop/cop/rspec/let_setup.rb +21 -6
- data/lib/rubocop/cop/rspec/message_chain.rb +7 -6
- data/lib/rubocop/cop/rspec/message_expectation.rb +2 -2
- data/lib/rubocop/cop/rspec/message_spies.rb +2 -3
- data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_describes.rb +11 -8
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +7 -11
- data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +148 -0
- data/lib/rubocop/cop/rspec/multiple_subjects.rb +18 -19
- data/lib/rubocop/cop/rspec/named_subject.rb +8 -8
- data/lib/rubocop/cop/rspec/nested_groups.rb +12 -13
- data/lib/rubocop/cop/rspec/not_to_not.rb +5 -6
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/pending.rb +1 -1
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +32 -69
- data/lib/rubocop/cop/rspec/rails/http_status.rb +7 -9
- data/lib/rubocop/cop/rspec/receive_counts.rb +15 -17
- data/lib/rubocop/cop/rspec/receive_never.rb +12 -12
- data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
- data/lib/rubocop/cop/rspec/repeated_example.rb +2 -2
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +12 -2
- data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +1 -1
- data/lib/rubocop/cop/rspec/return_from_stub.rb +12 -22
- data/lib/rubocop/cop/rspec/scattered_let.rb +12 -2
- data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/shared_context.rb +8 -21
- data/lib/rubocop/cop/rspec/shared_examples.rb +7 -9
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +15 -18
- data/lib/rubocop/cop/rspec/subject_stub.rb +25 -53
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -1
- data/lib/rubocop/cop/rspec/variable_definition.rb +56 -0
- data/lib/rubocop/cop/rspec/variable_name.rb +66 -0
- data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
- data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/yield.rb +14 -11
- data/lib/rubocop/cop/rspec_cops.rb +6 -1
- data/lib/rubocop/rspec/corrector/move_node.rb +54 -0
- data/lib/rubocop/rspec/description_extractor.rb +2 -6
- data/lib/rubocop/rspec/{blank_line_separation.rb → empty_line_separation.rb} +13 -10
- data/lib/rubocop/rspec/example_group.rb +21 -49
- data/lib/rubocop/rspec/factory_bot.rb +7 -1
- data/lib/rubocop/rspec/language.rb +13 -3
- data/lib/rubocop/rspec/language/node_pattern.rb +11 -2
- data/lib/rubocop/rspec/top_level_describe.rb +2 -2
- data/lib/rubocop/rspec/top_level_group.rb +55 -0
- data/lib/rubocop/rspec/variable.rb +16 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +36 -13
- data/lib/rubocop/rspec/util.rb +0 -19
@@ -24,7 +24,7 @@ module RuboCop
|
|
24
24
|
# # good
|
25
25
|
# expect(foo).to receive(:bar)
|
26
26
|
#
|
27
|
-
class MessageSpies <
|
27
|
+
class MessageSpies < Base
|
28
28
|
include ConfigurableEnforcedStyle
|
29
29
|
|
30
30
|
MSG_RECEIVE = 'Prefer `receive` for setting message expectations.'
|
@@ -48,8 +48,7 @@ module RuboCop
|
|
48
48
|
return correct_style_detected if preferred_style?(message_matcher)
|
49
49
|
|
50
50
|
add_offense(
|
51
|
-
message_matcher,
|
52
|
-
location: :selector,
|
51
|
+
message_matcher.loc.selector,
|
53
52
|
message: error_message(receiver)
|
54
53
|
) { opposite_style_detected }
|
55
54
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module RSpec
|
6
|
-
# Checks for multiple top
|
6
|
+
# Checks for multiple top-level example groups.
|
7
7
|
#
|
8
8
|
# Multiple descriptions for the same class or module should either
|
9
9
|
# be nested or separated into different test files.
|
@@ -22,17 +22,20 @@ module RuboCop
|
|
22
22
|
# describe '.do_something_else' do
|
23
23
|
# end
|
24
24
|
# end
|
25
|
-
class MultipleDescribes <
|
26
|
-
include RuboCop::RSpec::
|
25
|
+
class MultipleDescribes < Base
|
26
|
+
include RuboCop::RSpec::TopLevelGroup
|
27
27
|
|
28
|
-
MSG = 'Do not use multiple top
|
28
|
+
MSG = 'Do not use multiple top-level example groups - '\
|
29
29
|
'try to nest them.'
|
30
30
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
31
|
+
def on_top_level_group(node)
|
32
|
+
top_level_example_groups =
|
33
|
+
top_level_groups.select(&method(:example_group?))
|
34
34
|
|
35
|
-
|
35
|
+
return if top_level_example_groups.one?
|
36
|
+
return unless top_level_example_groups.first.equal?(node)
|
37
|
+
|
38
|
+
add_offense(node.send_node)
|
36
39
|
end
|
37
40
|
end
|
38
41
|
end
|
@@ -45,22 +45,18 @@ module RuboCop
|
|
45
45
|
# end
|
46
46
|
# end
|
47
47
|
#
|
48
|
-
class MultipleExpectations <
|
48
|
+
class MultipleExpectations < Base
|
49
49
|
include ConfigurableMax
|
50
50
|
|
51
51
|
MSG = 'Example has too many expectations [%<total>d/%<max>d].'
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
(send _ _ <(sym :aggregate_failures) ...>)
|
56
|
-
(send _ _ ... (hash <(pair (sym :aggregate_failures) true) ...>))
|
57
|
-
} ...)
|
58
|
-
PATTERN
|
53
|
+
ANYTHING = ->(_node) { true }
|
54
|
+
TRUE = ->(node) { node.true_type? }
|
59
55
|
|
60
|
-
def_node_matcher :
|
56
|
+
def_node_matcher :aggregate_failures?, <<-PATTERN
|
61
57
|
(block {
|
62
58
|
(send _ _ <(sym :aggregate_failures) ...>)
|
63
|
-
(send _ _ ... (hash <(pair (sym :aggregate_failures)
|
59
|
+
(send _ _ ... (hash <(pair (sym :aggregate_failures) %1) ...>))
|
64
60
|
} ...)
|
65
61
|
PATTERN
|
66
62
|
|
@@ -89,12 +85,12 @@ module RuboCop
|
|
89
85
|
node_with_aggregate_failures = find_aggregate_failures(example_node)
|
90
86
|
return false unless node_with_aggregate_failures
|
91
87
|
|
92
|
-
aggregate_failures?(node_with_aggregate_failures)
|
88
|
+
aggregate_failures?(node_with_aggregate_failures, TRUE)
|
93
89
|
end
|
94
90
|
|
95
91
|
def find_aggregate_failures(example_node)
|
96
92
|
example_node.send_node.each_ancestor(:block)
|
97
|
-
.find { |block_node|
|
93
|
+
.find { |block_node| aggregate_failures?(block_node, ANYTHING) }
|
98
94
|
end
|
99
95
|
|
100
96
|
def find_expectation(node, &block)
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks if example groups contain too many `let` and `subject` calls.
|
7
|
+
#
|
8
|
+
# This cop is configurable using the `Max` option and the `AllowSubject`
|
9
|
+
# which will configure the cop to only register offenses on calls to
|
10
|
+
# `let` and not calls to `subject`.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # bad
|
14
|
+
# describe MyClass do
|
15
|
+
# let(:foo) { [] }
|
16
|
+
# let(:bar) { [] }
|
17
|
+
# let!(:baz) { [] }
|
18
|
+
# let(:qux) { [] }
|
19
|
+
# let(:quux) { [] }
|
20
|
+
# let(:quuz) { {} }
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# describe MyClass do
|
24
|
+
# let(:foo) { [] }
|
25
|
+
# let(:bar) { [] }
|
26
|
+
# let!(:baz) { [] }
|
27
|
+
#
|
28
|
+
# context 'when stuff' do
|
29
|
+
# let(:qux) { [] }
|
30
|
+
# let(:quux) { [] }
|
31
|
+
# let(:quuz) { {} }
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# describe MyClass do
|
37
|
+
# let(:bar) { [] }
|
38
|
+
# let!(:baz) { [] }
|
39
|
+
# let(:qux) { [] }
|
40
|
+
# let(:quux) { [] }
|
41
|
+
# let(:quuz) { {} }
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# describe MyClass do
|
45
|
+
# context 'when stuff' do
|
46
|
+
# let(:foo) { [] }
|
47
|
+
# let(:bar) { [] }
|
48
|
+
# let!(:booger) { [] }
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# context 'when other stuff' do
|
52
|
+
# let(:qux) { [] }
|
53
|
+
# let(:quux) { [] }
|
54
|
+
# let(:quuz) { {} }
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# @example when disabling AllowSubject configuration
|
59
|
+
#
|
60
|
+
# # rubocop.yml
|
61
|
+
# # RSpec/MultipleMemoizedHelpers:
|
62
|
+
# # AllowSubject: false
|
63
|
+
#
|
64
|
+
# # bad - `subject` counts towards memoized helpers
|
65
|
+
# describe MyClass do
|
66
|
+
# subject { {} }
|
67
|
+
# let(:foo) { [] }
|
68
|
+
# let(:bar) { [] }
|
69
|
+
# let!(:baz) { [] }
|
70
|
+
# let(:qux) { [] }
|
71
|
+
# let(:quux) { [] }
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# @example with Max configuration
|
75
|
+
#
|
76
|
+
# # rubocop.yml
|
77
|
+
# # RSpec/MultipleMemoizedHelpers:
|
78
|
+
# # Max: 1
|
79
|
+
#
|
80
|
+
# # bad
|
81
|
+
# describe MyClass do
|
82
|
+
# let(:foo) { [] }
|
83
|
+
# let(:bar) { [] }
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
class MultipleMemoizedHelpers < Base
|
87
|
+
include ConfigurableMax
|
88
|
+
include RuboCop::RSpec::Variable
|
89
|
+
|
90
|
+
MSG = 'Example group has too many memoized helpers [%<count>d/%<max>d]'
|
91
|
+
|
92
|
+
def on_block(node)
|
93
|
+
return unless spec_group?(node)
|
94
|
+
|
95
|
+
count = all_helpers(node).uniq.count
|
96
|
+
|
97
|
+
return if count <= max
|
98
|
+
|
99
|
+
self.max = count
|
100
|
+
add_offense(node, message: format(MSG, count: count, max: max))
|
101
|
+
end
|
102
|
+
|
103
|
+
def on_new_investigation
|
104
|
+
@example_group_memoized_helpers = {}
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
attr_reader :example_group_memoized_helpers
|
110
|
+
|
111
|
+
def all_helpers(node)
|
112
|
+
[
|
113
|
+
*helpers(node),
|
114
|
+
*node.each_ancestor(:block).flat_map(&method(:helpers))
|
115
|
+
]
|
116
|
+
end
|
117
|
+
|
118
|
+
def helpers(node)
|
119
|
+
@example_group_memoized_helpers[node] ||=
|
120
|
+
variable_nodes(node).map do |variable_node|
|
121
|
+
if variable_node.block_type?
|
122
|
+
variable_definition?(variable_node.send_node)
|
123
|
+
else # block-pass (`let(:foo, &bar)`)
|
124
|
+
variable_definition?(variable_node)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def variable_nodes(node)
|
130
|
+
example_group = RuboCop::RSpec::ExampleGroup.new(node)
|
131
|
+
if allow_subject?
|
132
|
+
example_group.lets
|
133
|
+
else
|
134
|
+
example_group.lets + example_group.subjects
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def max
|
139
|
+
cop_config['Max']
|
140
|
+
end
|
141
|
+
|
142
|
+
def allow_subject?
|
143
|
+
cop_config['AllowSubject']
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -33,7 +33,8 @@ module RuboCop
|
|
33
33
|
# - If subjects are defined with `subject!` then we don't autocorrect.
|
34
34
|
# This is enough of an edge case that people can just move this to
|
35
35
|
# a `before` hook on their own
|
36
|
-
class MultipleSubjects <
|
36
|
+
class MultipleSubjects < Base
|
37
|
+
extend AutoCorrector
|
37
38
|
include RangeHelp
|
38
39
|
|
39
40
|
MSG = 'Do not set more than one subject per example group'
|
@@ -44,38 +45,36 @@ module RuboCop
|
|
44
45
|
subjects = RuboCop::RSpec::ExampleGroup.new(node).subjects
|
45
46
|
|
46
47
|
subjects[0...-1].each do |subject|
|
47
|
-
add_offense(subject)
|
48
|
+
add_offense(subject) do |corrector|
|
49
|
+
autocorrect(corrector, subject)
|
50
|
+
end
|
48
51
|
end
|
49
52
|
end
|
50
53
|
|
51
|
-
|
52
|
-
|
54
|
+
private
|
55
|
+
|
56
|
+
def autocorrect(corrector, subject)
|
57
|
+
return unless subject.method_name.equal?(:subject) # Ignore `subject!`
|
53
58
|
|
54
|
-
if named_subject?(
|
55
|
-
rename_autocorrect(
|
59
|
+
if named_subject?(subject)
|
60
|
+
rename_autocorrect(corrector, subject)
|
56
61
|
else
|
57
|
-
remove_autocorrect(
|
62
|
+
remove_autocorrect(corrector, subject)
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
61
|
-
private
|
62
|
-
|
63
66
|
def named_subject?(node)
|
64
67
|
node.send_node.arguments?
|
65
68
|
end
|
66
69
|
|
67
|
-
def rename_autocorrect(node)
|
68
|
-
|
69
|
-
corrector.replace(node.send_node.loc.selector, 'let')
|
70
|
-
end
|
70
|
+
def rename_autocorrect(corrector, node)
|
71
|
+
corrector.replace(node.send_node.loc.selector, 'let')
|
71
72
|
end
|
72
73
|
|
73
|
-
def remove_autocorrect(node)
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
corrector.remove(range)
|
78
|
-
end
|
74
|
+
def remove_autocorrect(corrector, node)
|
75
|
+
range = range_by_whole_lines(node.source_range,
|
76
|
+
include_final_newline: true)
|
77
|
+
corrector.remove(range)
|
79
78
|
end
|
80
79
|
end
|
81
80
|
end
|
@@ -6,11 +6,11 @@ module RuboCop
|
|
6
6
|
# Checks for explicitly referenced test subjects.
|
7
7
|
#
|
8
8
|
# RSpec lets you declare an "implicit subject" using `subject { ... }`
|
9
|
-
# which allows for tests like `it {
|
10
|
-
# reference your test subject you should explicitly
|
11
|
-
# `subject(:your_subject_name) { ... }`. Your test subjects
|
12
|
-
# the most important object in your tests so they deserve
|
13
|
-
# name.
|
9
|
+
# which allows for tests like `it { is_expected.to be_valid }`.
|
10
|
+
# If you need to reference your test subject you should explicitly
|
11
|
+
# name it using `subject(:your_subject_name) { ... }`. Your test subjects
|
12
|
+
# should be the most important object in your tests so they deserve
|
13
|
+
# a descriptive name.
|
14
14
|
#
|
15
15
|
# This cop can be configured in your configuration using the
|
16
16
|
# `IgnoreSharedExamples` which will not report offenses for implicit
|
@@ -39,9 +39,9 @@ module RuboCop
|
|
39
39
|
# RSpec.describe Foo do
|
40
40
|
# subject(:user) { described_class.new }
|
41
41
|
#
|
42
|
-
# it {
|
42
|
+
# it { is_expected.to be_valid }
|
43
43
|
# end
|
44
|
-
class NamedSubject <
|
44
|
+
class NamedSubject < Base
|
45
45
|
MSG = 'Name your test subject if you need '\
|
46
46
|
'to reference it explicitly.'
|
47
47
|
|
@@ -62,7 +62,7 @@ module RuboCop
|
|
62
62
|
return if !rspec_block?(node) || ignored_shared_example?(node)
|
63
63
|
|
64
64
|
subject_usage(node) do |subject_node|
|
65
|
-
add_offense(subject_node
|
65
|
+
add_offense(subject_node.loc.selector)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -85,9 +85,9 @@ module RuboCop
|
|
85
85
|
# end
|
86
86
|
# end
|
87
87
|
#
|
88
|
-
class NestedGroups <
|
88
|
+
class NestedGroups < Base
|
89
89
|
include ConfigurableMax
|
90
|
-
include RuboCop::RSpec::
|
90
|
+
include RuboCop::RSpec::TopLevelGroup
|
91
91
|
|
92
92
|
MSG = 'Maximum example group nesting exceeded [%<total>d/%<max>d].'
|
93
93
|
|
@@ -97,13 +97,11 @@ module RuboCop
|
|
97
97
|
"Configuration key `#{DEPRECATED_MAX_KEY}` for #{cop_name} is " \
|
98
98
|
'deprecated in favor of `Max`. Please use that instead.'
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
def on_top_level_describe(node, _args)
|
103
|
-
find_nested_contexts(node.parent) do |context, nesting|
|
100
|
+
def on_top_level_group(node)
|
101
|
+
find_nested_example_groups(node) do |example_group, nesting|
|
104
102
|
self.max = nesting
|
105
103
|
add_offense(
|
106
|
-
|
104
|
+
example_group.send_node,
|
107
105
|
message: message(nesting)
|
108
106
|
)
|
109
107
|
end
|
@@ -111,13 +109,14 @@ module RuboCop
|
|
111
109
|
|
112
110
|
private
|
113
111
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
112
|
+
def find_nested_example_groups(node, nesting: 1, &block)
|
113
|
+
example_group = example_group?(node)
|
114
|
+
yield node, nesting if example_group && nesting > max_nesting
|
115
|
+
|
116
|
+
next_nesting = example_group ? nesting + 1 : nesting
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
end
|
118
|
+
node.each_child_node(:block, :begin) do |child|
|
119
|
+
find_nested_example_groups(child, nesting: next_nesting, &block)
|
121
120
|
end
|
122
121
|
end
|
123
122
|
|
@@ -15,7 +15,8 @@ module RuboCop
|
|
15
15
|
# it '...' do
|
16
16
|
# expect(false).not_to be_true
|
17
17
|
# end
|
18
|
-
class NotToNot <
|
18
|
+
class NotToNot < Base
|
19
|
+
extend AutoCorrector
|
19
20
|
include ConfigurableEnforcedStyle
|
20
21
|
|
21
22
|
MSG = 'Prefer `%<replacement>s` over `%<original>s`.'
|
@@ -24,14 +25,12 @@ module RuboCop
|
|
24
25
|
|
25
26
|
def on_send(node)
|
26
27
|
not_to_not_offense(node, alternative_style) do
|
27
|
-
add_offense(node
|
28
|
+
add_offense(node.loc.selector) do |corrector|
|
29
|
+
corrector.replace(node.loc.selector, style.to_s)
|
30
|
+
end
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
|
-
def autocorrect(node)
|
32
|
-
->(corrector) { corrector.replace(node.loc.selector, style.to_s) }
|
33
|
-
end
|
34
|
-
|
35
34
|
private
|
36
35
|
|
37
36
|
def message(_node)
|
@@ -21,7 +21,7 @@ module RuboCop
|
|
21
21
|
# let(:foo) { bar }
|
22
22
|
# let(:baz) { baz }
|
23
23
|
# let!(:other) { other }
|
24
|
-
class OverwritingSetup <
|
24
|
+
class OverwritingSetup < Base
|
25
25
|
MSG = '`%<name>s` is already defined.'
|
26
26
|
|
27
27
|
def_node_matcher :setup?, (Helpers::ALL + Subject::ALL).block_pattern
|