Skip to content

Commit 24eaa3e

Browse files
committed
Use runtime matchers for hooks
In order to make matchers be able to fetch hooks from configuration.
1 parent 24bdc39 commit 24eaa3e

File tree

8 files changed

+72
-49
lines changed

8 files changed

+72
-49
lines changed

lib/rubocop/cop/rspec/described_class.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@ class DescribedClass < Base
6565
(block (send (const nil? {:Class :Module :Struct}) :new ...) ...)
6666
PATTERN
6767

68-
def_node_matcher :rspec_block?,
69-
RuboCop::RSpec::Language::ALL.block_pattern
68+
def_runtime_node_matcher :rspec_block? do
69+
all_selectors.block_pattern
70+
end
7071

7172
def_node_matcher :scope_changing_syntax?, '{def class module}'
7273

lib/rubocop/cop/rspec/dialect.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ class Dialect < Base
4747

4848
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
4949

50-
def_node_matcher :rspec_method?, ALL.send_pattern
50+
def_runtime_node_matcher :rspec_method? do
51+
all_selectors.send_pattern
52+
end
5153

5254
def on_send(node)
5355
return unless rspec_method?(node)

lib/rubocop/cop/rspec/empty_hook.rb

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,13 @@ class EmptyHook < Base
2828

2929
MSG = 'Empty hook detected.'
3030

31-
def_node_matcher :empty_hook?, <<~PATTERN
32-
(block $#{Hooks::ALL.send_pattern} _ nil?)
33-
PATTERN
34-
3531
def on_block(node)
36-
empty_hook?(node) do |hook|
37-
add_offense(hook) do |corrector|
38-
range = range_with_surrounding_space(range: node.loc.expression)
39-
corrector.remove(range)
40-
end
32+
return unless hook?(node)
33+
return unless node.body.nil?
34+
35+
add_offense(node.send_node) do |corrector|
36+
range = range_with_surrounding_space(range: node.loc.expression)
37+
corrector.remove(range)
4138
end
4239
end
4340
end

lib/rubocop/cop/rspec/hook_argument.rb

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,17 @@ class HookArgument < Base
6464
IMPLICIT_MSG = 'Omit the default `%<scope>p` argument for RSpec hooks.'
6565
EXPLICIT_MSG = 'Use `%<scope>p` for RSpec hooks.'
6666

67-
def_node_matcher :hook?, Hooks::ALL.node_pattern_union
67+
def_node_matcher :hook?, hook_selectors.node_pattern_union
6868

69-
def_node_matcher :scoped_hook, <<-PATTERN
70-
(block $(send _ #hook? (sym ${:each :example})) ...)
71-
PATTERN
69+
def_runtime_node_matcher :scoped_hook do
70+
<<-PATTERN
71+
(block $(send _ #hook? (sym ${:each :example})) ...)
72+
PATTERN
73+
end
7274

73-
def_node_matcher :unscoped_hook, '(block $(send _ #hook?) ...)'
75+
def_runtime_node_matcher :unscoped_hook do
76+
"(block $(send _ #hook?) ...)"
77+
end
7478

7579
def on_block(node)
7680
hook(node) do |method_send, scope_name|

lib/rubocop/cop/rspec/named_subject.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@ class NamedSubject < Base
4545
MSG = 'Name your test subject if you need '\
4646
'to reference it explicitly.'
4747

48-
def_node_matcher :rspec_block?, <<-PATTERN
49-
{
50-
#{Examples::ALL.block_pattern}
51-
#{Hooks::ALL.block_pattern}
52-
}
53-
PATTERN
48+
def_runtime_node_matcher :rspec_block? do
49+
<<-PATTERN
50+
{
51+
#{Examples::ALL.block_pattern}
52+
#{hook_selectors.block_pattern}
53+
}
54+
PATTERN
55+
end
5456

5557
def_node_matcher :shared_example?, <<-PATTERN
5658
#{SharedGroups::EXAMPLES.block_pattern}

lib/rubocop/cop/rspec/shared_context.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,14 @@ class SharedContext < Base
6161

6262
examples = (Examples::ALL + Includes::EXAMPLES)
6363
def_node_search :examples?, examples.send_pattern
64-
65-
context = (Hooks::ALL + Helpers::ALL + Includes::CONTEXT + Subject::ALL)
66-
def_node_search :context?, context.send_pattern
64+
def_runtime_node_search :context? do
65+
(
66+
hook_selectors +
67+
Helpers::ALL +
68+
Includes::CONTEXT +
69+
Subject::ALL
70+
).send_pattern
71+
end
6772

6873
def_node_matcher :shared_context, SharedGroups::CONTEXT.block_pattern
6974
def_node_matcher :shared_example, SharedGroups::EXAMPLES.block_pattern

lib/rubocop/rspec/language.rb

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,15 @@ module Examples
9393
end
9494

9595
module Hooks
96-
ALL = SelectorSet.new(
97-
%i[
98-
prepend_before
99-
before
100-
append_before
101-
around
102-
prepend_after
103-
after
104-
append_after
105-
]
106-
)
96+
BUILT_IN_METHOD_NAMES = %i[
97+
prepend_before
98+
before
99+
append_before
100+
around
101+
prepend_after
102+
after
103+
append_after
104+
].freeze
107105

108106
module Scopes
109107
ALL = SelectorSet.new(
@@ -133,16 +131,6 @@ module Expectations
133131
module Runners
134132
ALL = SelectorSet.new(%i[to to_not not_to])
135133
end
136-
137-
ALL =
138-
ExampleGroups::ALL +
139-
SharedGroups::ALL +
140-
Examples::ALL +
141-
Hooks::ALL +
142-
Helpers::ALL +
143-
Subject::ALL +
144-
Expectations::ALL +
145-
Runners::ALL
146134
end
147135
end
148136
end

lib/rubocop/rspec/language/node_pattern.rb

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,38 @@ module NodePattern
2222

2323
def_node_matcher :example?, Examples::ALL.block_pattern
2424

25-
def_node_matcher :hook?, Hooks::ALL.block_pattern
26-
2725
def_node_matcher :let?, Helpers::ALL.block_or_block_pass_pattern
2826

2927
def_node_matcher :include?,
3028
Includes::ALL.send_or_block_or_block_pass_pattern
3129

3230
def_node_matcher :subject?, Subject::ALL.block_pattern
31+
32+
def_runtime_node_matcher :hook? do
33+
hook_selectors.block_pattern
34+
end
35+
36+
def hook_selectors
37+
custom_method_names = config
38+
.for_all_cops
39+
.fetch('RSpec', {})
40+
.fetch('Language', {})
41+
.fetch('Hooks', [])
42+
.map(&:to_sym)
43+
44+
SelectorSet.new(Hooks::BUILT_IN_METHOD_NAMES + custom_method_names)
45+
end
46+
47+
def all_selectors
48+
ExampleGroups::ALL +
49+
SharedGroups::ALL +
50+
Examples::ALL +
51+
hook_selectors +
52+
Helpers::ALL +
53+
Subject::ALL +
54+
Expectations::ALL +
55+
Runners::ALL
56+
end
3357
end
3458
end
3559
end

0 commit comments

Comments
 (0)