rubocop-rspec 1.12.0 → 1.13.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 +11 -0
- data/config/default.yml +15 -1
- data/lib/rubocop-rspec.rb +2 -0
- data/lib/rubocop/cop/rspec/any_instance.rb +7 -10
- data/lib/rubocop/cop/rspec/around_block.rb +19 -30
- data/lib/rubocop/cop/rspec/be_eql.rb +3 -7
- data/lib/rubocop/cop/rspec/before_after_all.rb +10 -16
- data/lib/rubocop/cop/rspec/cop.rb +5 -1
- data/lib/rubocop/cop/rspec/describe_class.rb +8 -8
- data/lib/rubocop/cop/rspec/describe_method.rb +6 -5
- data/lib/rubocop/cop/rspec/described_class.rb +2 -2
- data/lib/rubocop/cop/rspec/example_length.rb +5 -8
- data/lib/rubocop/cop/rspec/example_wording.rb +57 -23
- data/lib/rubocop/cop/rspec/expect_actual.rb +3 -9
- data/lib/rubocop/cop/rspec/expect_output.rb +2 -2
- data/lib/rubocop/cop/rspec/file_path.rb +30 -29
- data/lib/rubocop/cop/rspec/hook_argument.rb +1 -1
- data/lib/rubocop/cop/rspec/instance_spy.rb +12 -12
- data/lib/rubocop/cop/rspec/instance_variable.rb +2 -2
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +47 -0
- data/lib/rubocop/cop/rspec/leading_subject.rb +1 -1
- data/lib/rubocop/cop/rspec/message_chain.rb +7 -4
- data/lib/rubocop/cop/rspec/message_spies.rb +6 -5
- data/lib/rubocop/cop/rspec/multiple_describes.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +38 -6
- data/lib/rubocop/cop/rspec/named_subject.rb +2 -2
- data/lib/rubocop/cop/rspec/nested_groups.rb +10 -6
- data/lib/rubocop/cop/rspec/not_to_not.rb +12 -23
- data/lib/rubocop/cop/rspec/shared_context.rb +107 -0
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +16 -23
- data/lib/rubocop/cop/rspec/subject_stub.rb +4 -4
- data/lib/rubocop/cop/rspec/verified_doubles.rb +4 -3
- data/lib/rubocop/rspec/example_group.rb +1 -1
- data/lib/rubocop/rspec/language.rb +25 -7
- data/lib/rubocop/rspec/version.rb +1 -1
- data/spec/expect_violation/expectation_spec.rb +16 -16
- data/spec/project/changelog_spec.rb +1 -1
- data/spec/project/default_config_spec.rb +1 -1
- data/spec/project/project_requires_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/any_instance_spec.rb +4 -4
- data/spec/rubocop/cop/rspec/around_block_spec.rb +115 -26
- data/spec/rubocop/cop/rspec/be_eql_spec.rb +9 -9
- data/spec/rubocop/cop/rspec/before_after_all_spec.rb +38 -80
- data/spec/rubocop/cop/rspec/describe_class_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/describe_method_spec.rb +2 -2
- data/spec/rubocop/cop/rspec/described_class_spec.rb +13 -13
- data/spec/rubocop/cop/rspec/empty_example_group_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/example_length_spec.rb +3 -32
- data/spec/rubocop/cop/rspec/example_wording_spec.rb +21 -2
- data/spec/rubocop/cop/rspec/expect_actual_spec.rb +33 -18
- data/spec/rubocop/cop/rspec/expect_output_spec.rb +3 -3
- data/spec/rubocop/cop/rspec/file_path_spec.rb +119 -170
- data/spec/rubocop/cop/rspec/focus_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/hook_argument_spec.rb +1 -3
- data/spec/rubocop/cop/rspec/implicit_expect_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/instance_spy_spec.rb +11 -11
- data/spec/rubocop/cop/rspec/instance_variable_spec.rb +4 -4
- data/spec/rubocop/cop/rspec/it_behaves_like_spec.rb +51 -0
- data/spec/rubocop/cop/rspec/leading_subject_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/let_setup_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/message_chain_spec.rb +3 -3
- data/spec/rubocop/cop/rspec/message_expectation_spec.rb +5 -23
- data/spec/rubocop/cop/rspec/message_spies_spec.rb +9 -23
- data/spec/rubocop/cop/rspec/multiple_describes_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/multiple_expectations_spec.rb +66 -3
- data/spec/rubocop/cop/rspec/nested_groups_spec.rb +4 -4
- data/spec/rubocop/cop/rspec/not_to_not_spec.rb +3 -3
- data/spec/rubocop/cop/rspec/repeated_description_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/repeated_example_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/scattered_setup_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/shared_context_spec.rb +142 -0
- data/spec/rubocop/cop/rspec/single_argument_message_chain_spec.rb +5 -5
- data/spec/rubocop/cop/rspec/subject_stub_spec.rb +1 -1
- data/spec/rubocop/cop/rspec/verified_doubles_spec.rb +2 -2
- data/spec/rubocop/rspec/config_formatter_spec.rb +12 -12
- data/spec/rubocop/rspec/description_extractor_spec.rb +23 -23
- data/spec/rubocop/rspec/example_group_spec.rb +11 -11
- data/spec/rubocop/rspec/example_spec.rb +1 -1
- data/spec/rubocop/rspec/language/selector_set_spec.rb +1 -1
- data/spec/rubocop/rspec/util/one_spec.rb +1 -1
- data/spec/rubocop/rspec/wording_spec.rb +1 -1
- data/spec/shared/detects_style_behavior.rb +3 -4
- data/spec/spec_helper.rb +10 -0
- metadata +8 -2
@@ -17,7 +17,7 @@ module RuboCop
|
|
17
17
|
# expect(name).to eq("John")
|
18
18
|
#
|
19
19
|
class ExpectActual < Cop
|
20
|
-
MSG = 'Provide the actual you are testing to `expect(...)
|
20
|
+
MSG = 'Provide the actual you are testing to `expect(...)`.'.freeze
|
21
21
|
|
22
22
|
SIMPLE_LITERALS = %i(
|
23
23
|
true
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
regexp
|
42
42
|
).freeze
|
43
43
|
|
44
|
-
def_node_matcher :
|
44
|
+
def_node_matcher :expect_literal, '(send _ :expect $#literal?)'
|
45
45
|
|
46
46
|
def on_send(node)
|
47
47
|
expect_literal(node) do |argument|
|
@@ -53,14 +53,8 @@ module RuboCop
|
|
53
53
|
|
54
54
|
# This is not implement using a NodePattern because it seems
|
55
55
|
# to not be able to match against an explicit (nil) sexp
|
56
|
-
def expect_literal(node)
|
57
|
-
return unless (argument = expect(node))
|
58
|
-
|
59
|
-
yield(argument) if literal?(argument)
|
60
|
-
end
|
61
|
-
|
62
56
|
def literal?(node)
|
63
|
-
simple_literal?(node) || complex_literal?(node)
|
57
|
+
node && (simple_literal?(node) || complex_literal?(node))
|
64
58
|
end
|
65
59
|
|
66
60
|
def simple_literal?(node)
|
@@ -15,8 +15,8 @@ module RuboCop
|
|
15
15
|
# # good
|
16
16
|
# expect { my_app.print_report }.to output('Hello World').to_stdout
|
17
17
|
class ExpectOutput < Cop
|
18
|
-
MSG = 'Use `expect { ... }.to output(...).to_%<name>s` '
|
19
|
-
'instead of mutating $%<name>s'.freeze
|
18
|
+
MSG = 'Use `expect { ... }.to output(...).to_%<name>s` '\
|
19
|
+
'instead of mutating $%<name>s.'.freeze
|
20
20
|
|
21
21
|
def_node_matcher :hook?, Hooks::ALL.block_pattern
|
22
22
|
|
@@ -44,66 +44,67 @@ module RuboCop
|
|
44
44
|
class FilePath < Cop
|
45
45
|
include RuboCop::RSpec::TopLevelDescribe
|
46
46
|
|
47
|
-
|
48
|
-
|
47
|
+
MSG = 'Spec path should end with `%s`.'.freeze
|
48
|
+
|
49
|
+
def_node_search :const_described?, '(send _ :describe (const ...) ...)'
|
50
|
+
def_node_search :routing_metadata?, '(pair (sym :type) (sym :routing))'
|
49
51
|
|
50
52
|
def on_top_level_describe(node, args)
|
53
|
+
return unless const_described?(node) && single_top_level_describe?
|
51
54
|
return if routing_spec?(args)
|
52
55
|
|
53
|
-
|
54
|
-
object = args.first.const_name
|
55
|
-
return unless object
|
56
|
+
glob = glob_for(args)
|
56
57
|
|
57
|
-
|
58
|
-
return if source_filename =~ regexp_from_glob(path_matcher)
|
58
|
+
return if filename_ends_with?(glob)
|
59
59
|
|
60
|
-
add_offense(node, :expression, format(
|
60
|
+
add_offense(node, :expression, format(MSG, glob))
|
61
61
|
end
|
62
62
|
|
63
63
|
private
|
64
64
|
|
65
65
|
def routing_spec?(args)
|
66
|
-
args.any?
|
67
|
-
arg.children.include?(ROUTING_PAIR)
|
68
|
-
end
|
66
|
+
args.any?(&method(:routing_metadata?))
|
69
67
|
end
|
70
68
|
|
71
|
-
def
|
72
|
-
|
73
|
-
if method && method.type.equal?(:str) && !ignore_methods?
|
74
|
-
path += '*' + method.str_content.gsub(/\W+/, '')
|
75
|
-
end
|
76
|
-
|
77
|
-
"#{path}*_spec.rb"
|
69
|
+
def glob_for((described_class, method_name))
|
70
|
+
"#{expected_path(described_class)}#{name_glob(method_name)}*_spec.rb"
|
78
71
|
end
|
79
72
|
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
73
|
+
def name_glob(name)
|
74
|
+
return unless name && name.str_type?
|
75
|
+
|
76
|
+
"*#{name.str_content.gsub(/\W/, '')}" unless ignore_methods?
|
84
77
|
end
|
85
78
|
|
86
|
-
def
|
87
|
-
|
79
|
+
def expected_path(constant)
|
80
|
+
File.join(
|
81
|
+
constant.const_name.split('::').map do |name|
|
82
|
+
custom_transform.fetch(name) { camel_to_snake_case(name) }
|
83
|
+
end
|
84
|
+
)
|
88
85
|
end
|
89
86
|
|
90
|
-
def
|
87
|
+
def camel_to_snake_case(string)
|
91
88
|
string
|
92
89
|
.gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
|
93
90
|
.gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2')
|
94
91
|
.downcase
|
95
92
|
end
|
96
93
|
|
97
|
-
def
|
98
|
-
|
94
|
+
def custom_transform
|
95
|
+
cop_config.fetch('CustomTransform', {})
|
99
96
|
end
|
100
97
|
|
101
98
|
def ignore_methods?
|
102
99
|
cop_config['IgnoreMethods']
|
103
100
|
end
|
104
101
|
|
105
|
-
def
|
106
|
-
|
102
|
+
def filename_ends_with?(glob)
|
103
|
+
File.fnmatch?("*#{glob}", processed_source.buffer.name)
|
104
|
+
end
|
105
|
+
|
106
|
+
def relevant_rubocop_rspec_file?(_)
|
107
|
+
true
|
107
108
|
end
|
108
109
|
end
|
109
110
|
end
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
HOOKS = Hooks::ALL.node_pattern_union.freeze
|
67
67
|
|
68
68
|
def_node_matcher :scoped_hook, <<-PATTERN
|
69
|
-
|
69
|
+
(block $(send nil #{HOOKS} (sym ${:each :example})) ...)
|
70
70
|
PATTERN
|
71
71
|
|
72
72
|
def_node_matcher :unscoped_hook, "(block $(send nil #{HOOKS}) ...)"
|
@@ -19,27 +19,27 @@ module RuboCop
|
|
19
19
|
# end
|
20
20
|
#
|
21
21
|
class InstanceSpy < Cop
|
22
|
-
MSG = 'Use `instance_spy` when you check your double '
|
23
|
-
'with `have_received
|
22
|
+
MSG = 'Use `instance_spy` when you check your double '\
|
23
|
+
'with `have_received`.'.freeze
|
24
24
|
|
25
25
|
EXAMPLES = Examples::ALL.node_pattern_union.freeze
|
26
26
|
|
27
27
|
def_node_matcher :example?, "(block $(send nil #{EXAMPLES}) ...)"
|
28
28
|
|
29
29
|
def_node_search :null_double, <<-PATTERN
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
(lvasgn $_
|
31
|
+
(send
|
32
|
+
$(send nil :instance_double
|
33
|
+
...) :as_null_object))
|
34
34
|
PATTERN
|
35
35
|
|
36
36
|
def_node_search :have_received_usage, <<-PATTERN
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
(send
|
38
|
+
(send nil :expect
|
39
|
+
(lvar $_)) :to
|
40
|
+
(send nil :have_received
|
41
|
+
...)
|
41
42
|
...)
|
42
|
-
...)
|
43
43
|
PATTERN
|
44
44
|
|
45
45
|
def on_block(node)
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
|
48
48
|
null_double(node) do |var, receiver|
|
49
49
|
have_received_usage(node) do |expected|
|
50
|
-
add_offense(receiver, :expression
|
50
|
+
add_offense(receiver, :expression) if expected == var
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
# end
|
48
48
|
#
|
49
49
|
class InstanceVariable < Cop
|
50
|
-
|
50
|
+
MSG = 'Use `let` instead of an instance variable.'.freeze
|
51
51
|
|
52
52
|
EXAMPLE_GROUP_METHODS = ExampleGroups::ALL + SharedGroups::ALL
|
53
53
|
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
63
63
|
ivar_usage(node) do |ivar, name|
|
64
64
|
return if assignment_only? && !ivar_assigned?(node, name)
|
65
65
|
|
66
|
-
add_offense(ivar, :expression
|
66
|
+
add_offense(ivar, :expression)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module RSpec
|
6
|
+
# Checks that only one `it_behaves_like` style is used.
|
7
|
+
#
|
8
|
+
# @example when configuration is `EnforcedStyle: it_behaves_like`
|
9
|
+
# # bad
|
10
|
+
# it_should_behave_like 'a foo'
|
11
|
+
#
|
12
|
+
# # good
|
13
|
+
# it_behaves_like 'a foo'
|
14
|
+
#
|
15
|
+
# @example when configuration is `EnforcedStyle: it_should_behave_like`
|
16
|
+
# # bad
|
17
|
+
# it_behaves_like 'a foo'
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# it_should_behave_like 'a foo'
|
21
|
+
class ItBehavesLike < Cop
|
22
|
+
include ConfigurableEnforcedStyle
|
23
|
+
|
24
|
+
MSG = 'Prefer `%s` over `%s` when including examples in '\
|
25
|
+
'a nested context.'.freeze
|
26
|
+
|
27
|
+
def_node_matcher :example_inclusion_offense, '(send _ % ...)'
|
28
|
+
|
29
|
+
def on_send(node)
|
30
|
+
example_inclusion_offense(node, alternative_style) do
|
31
|
+
add_offense(node, :expression)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def autocorrect(node)
|
36
|
+
->(corrector) { corrector.replace(node.loc.selector, style.to_s) }
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def message(_node)
|
42
|
+
format(MSG, style, alternative_style)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -27,7 +27,7 @@ module RuboCop
|
|
27
27
|
# end
|
28
28
|
# end
|
29
29
|
class LeadingSubject < Cop
|
30
|
-
MSG = 'Declare `subject` above any other `let` declarations'.freeze
|
30
|
+
MSG = 'Declare `subject` above any other `let` declarations.'.freeze
|
31
31
|
|
32
32
|
def_node_matcher :subject?, '(block $(send nil :subject ...) args ...)'
|
33
33
|
|
@@ -12,13 +12,16 @@ module RuboCop
|
|
12
12
|
# allow(foo).to receive(bar: thing)
|
13
13
|
#
|
14
14
|
class MessageChain < Cop
|
15
|
-
|
15
|
+
MSG = 'Avoid stubbing using `%<method>s`.'.freeze
|
16
|
+
|
17
|
+
def_node_matcher :message_chain, Matchers::MESSAGE_CHAIN.send_pattern
|
16
18
|
|
17
19
|
def on_send(node)
|
18
|
-
|
19
|
-
|
20
|
+
message_chain(node) { add_offense(node, :selector) }
|
21
|
+
end
|
20
22
|
|
21
|
-
|
23
|
+
def message(node)
|
24
|
+
format(MSG, method: node.method_name)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
@@ -27,11 +27,12 @@ module RuboCop
|
|
27
27
|
class MessageSpies < Cop
|
28
28
|
include ConfigurableEnforcedStyle
|
29
29
|
|
30
|
-
MSG_RECEIVE = 'Prefer `receive` for setting message '
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
MSG_RECEIVE = 'Prefer `receive` for setting message '\
|
31
|
+
'expectations.'.freeze
|
32
|
+
|
33
|
+
MSG_HAVE_RECEIVED = 'Prefer `have_received` for setting message '\
|
34
|
+
'expectations. Setup `%s` as a spy using `allow`'\
|
35
|
+
' or `instance_spy`.'.freeze
|
35
36
|
|
36
37
|
SUPPORTED_STYLES = %w(have_received receive).freeze
|
37
38
|
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
class MultipleDescribes < Cop
|
26
26
|
include RuboCop::RSpec::TopLevelDescribe
|
27
27
|
|
28
|
-
MSG = 'Do not use multiple top level describes - '
|
28
|
+
MSG = 'Do not use multiple top level describes - '\
|
29
29
|
'try to nest them.'.freeze
|
30
30
|
|
31
31
|
def on_top_level_describe(node, _args)
|
@@ -48,22 +48,54 @@ module RuboCop
|
|
48
48
|
class MultipleExpectations < Cop
|
49
49
|
include ConfigurableMax
|
50
50
|
|
51
|
-
MSG = 'Example has too many expectations [%{total}/%{max}]'.freeze
|
51
|
+
MSG = 'Example has too many expectations [%{total}/%{max}].'.freeze
|
52
52
|
|
53
|
-
def_node_search :
|
53
|
+
def_node_search :with_aggregated_failures?, '(sym :aggregate_failures)'
|
54
|
+
def_node_search :disabled_aggregated_failures?, <<-PATTERN
|
55
|
+
(pair (sym :aggregate_failures) (false))
|
56
|
+
PATTERN
|
57
|
+
|
58
|
+
def_node_matcher :expect?, '(send _ :expect ...)'
|
59
|
+
def_node_matcher :aggregate_failures?, <<-PATTERN
|
60
|
+
(block (send _ :aggregate_failures ...) ...)
|
61
|
+
PATTERN
|
54
62
|
|
55
63
|
def on_block(node)
|
56
|
-
return unless example?(node)
|
64
|
+
return unless example?(node)
|
65
|
+
|
66
|
+
return if example_with_aggregated_failures?(node)
|
67
|
+
|
68
|
+
expectations_count = to_enum(:find_expectation, node).count
|
57
69
|
|
58
|
-
return if
|
70
|
+
return if expectations_count <= max_expectations
|
59
71
|
|
60
|
-
self.max =
|
72
|
+
self.max = expectations_count
|
61
73
|
|
62
|
-
flag_example(node, expectation_count:
|
74
|
+
flag_example(node, expectation_count: expectations_count)
|
63
75
|
end
|
64
76
|
|
65
77
|
private
|
66
78
|
|
79
|
+
def example_with_aggregated_failures?(node)
|
80
|
+
example = node.children.first
|
81
|
+
|
82
|
+
with_aggregated_failures?(example) &&
|
83
|
+
!disabled_aggregated_failures?(example)
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_expectation(node, &block)
|
87
|
+
return unless node.is_a?(Parser::AST::Node)
|
88
|
+
|
89
|
+
yield if expect?(node) || aggregate_failures?(node)
|
90
|
+
|
91
|
+
# do not search inside of aggregate_failures block
|
92
|
+
return if aggregate_failures?(node)
|
93
|
+
|
94
|
+
node.children.each do |child|
|
95
|
+
find_expectation(child, &block)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
67
99
|
def flag_example(node, expectation_count:)
|
68
100
|
method, = *node
|
69
101
|
|
@@ -38,8 +38,8 @@ module RuboCop
|
|
38
38
|
# it { should be_valid }
|
39
39
|
# end
|
40
40
|
class NamedSubject < Cop
|
41
|
-
MSG = 'Name your test subject if '\
|
42
|
-
'
|
41
|
+
MSG = 'Name your test subject if you need '\
|
42
|
+
'to reference it explicitly.'.freeze
|
43
43
|
|
44
44
|
def_node_matcher :rspec_block?, <<-PATTERN
|
45
45
|
(block
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module RSpec
|
6
6
|
# Checks for nested example groups.
|
7
7
|
#
|
8
|
-
# This cop is configurable using the `
|
8
|
+
# This cop is configurable using the `Max` option
|
9
9
|
#
|
10
10
|
# @example
|
11
11
|
# # bad
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
56
56
|
#
|
57
57
|
# # .rubocop.yml
|
58
58
|
# RSpec/NestedGroups:
|
59
|
-
#
|
59
|
+
# Max: 2
|
60
60
|
#
|
61
61
|
# context 'when using some feature' do
|
62
62
|
# let(:some) { :various }
|
@@ -87,7 +87,7 @@ module RuboCop
|
|
87
87
|
class NestedGroups < Cop
|
88
88
|
include RuboCop::RSpec::TopLevelDescribe
|
89
89
|
|
90
|
-
MSG = 'Maximum example group nesting exceeded'.freeze
|
90
|
+
MSG = 'Maximum example group nesting exceeded [%d/%d].'.freeze
|
91
91
|
|
92
92
|
DEPRECATED_MAX_KEY = 'MaxNesting'.freeze
|
93
93
|
|
@@ -98,8 +98,8 @@ module RuboCop
|
|
98
98
|
def_node_search :find_contexts, ExampleGroups::ALL.block_pattern
|
99
99
|
|
100
100
|
def on_top_level_describe(node, _)
|
101
|
-
find_nested_contexts(node.parent) do |context|
|
102
|
-
add_offense(context.children.first, :expression)
|
101
|
+
find_nested_contexts(node.parent) do |context, nesting|
|
102
|
+
add_offense(context.children.first, :expression, message(nesting))
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
|
108
108
|
def find_nested_contexts(node, nesting: 1, &block)
|
109
109
|
find_contexts(node) do |nested_context|
|
110
|
-
yield(nested_context) if nesting > max_nesting
|
110
|
+
yield(nested_context, nesting) if nesting > max_nesting
|
111
111
|
|
112
112
|
nested_context.each_child_node do |child|
|
113
113
|
find_nested_contexts(child, nesting: nesting + 1, &block)
|
@@ -115,6 +115,10 @@ module RuboCop
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
def message(nesting)
|
119
|
+
format(MSG, nesting, max_nesting)
|
120
|
+
end
|
121
|
+
|
118
122
|
def max_nesting
|
119
123
|
@max_nesting ||= Integer(max_nesting_config)
|
120
124
|
end
|