Skip to content

Commit edc2c0e

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

File tree

8 files changed

+69
-48
lines changed

8 files changed

+69
-48
lines changed

lib/rubocop/cop/rspec/described_class.rb

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

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

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

lib/rubocop/cop/rspec/dialect.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ class Dialect < Cop
4646

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

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

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

lib/rubocop/cop/rspec/empty_hook.rb

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,11 @@ class EmptyHook < Cop
2727

2828
MSG = 'Empty hook detected.'
2929

30-
def_node_matcher :empty_hook?, <<~PATTERN
31-
(block $#{Hooks::ALL.send_pattern} _ nil?)
32-
PATTERN
33-
3430
def on_block(node)
35-
empty_hook?(node) do |hook|
36-
add_offense(hook)
37-
end
31+
return unless hook?(node)
32+
return unless node.body.nil?
33+
34+
add_offense(node.send_node)
3835
end
3936

4037
def autocorrect(node)

lib/rubocop/cop/rspec/hook_argument.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,15 @@ class HookArgument < Cop
6464
'argument for RSpec hooks.'
6565
EXPLICIT_MSG = 'Use `%<scope>p` for RSpec hooks.'
6666

67-
HOOKS = Hooks::ALL.node_pattern_union.freeze
68-
69-
def_node_matcher :scoped_hook, <<-PATTERN
70-
(block $(send _ #{HOOKS} (sym ${:each :example})) ...)
71-
PATTERN
67+
def_runtime_node_matcher :scoped_hook do
68+
<<-PATTERN
69+
(block $(send _ #{hook_selectors.node_pattern_union} (sym ${:each :example})) ...)
70+
PATTERN
71+
end
7272

73-
def_node_matcher :unscoped_hook, "(block $(send _ #{HOOKS}) ...)"
73+
def_runtime_node_matcher :unscoped_hook do
74+
"(block $(send _ #{hook_selectors.node_pattern_union}) ...)"
75+
end
7476

7577
def on_block(node)
7678
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 < Cop
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
@@ -59,9 +59,14 @@ class SharedContext < Cop
5959

6060
examples = (Examples::ALL + Includes::EXAMPLES)
6161
def_node_search :examples?, examples.send_pattern
62-
63-
context = (Hooks::ALL + Helpers::ALL + Includes::CONTEXT + Subject::ALL)
64-
def_node_search :context?, context.send_pattern
62+
def_runtime_node_search :context? do
63+
(
64+
hook_selectors +
65+
Helpers::ALL +
66+
Includes::CONTEXT +
67+
Subject::ALL
68+
).send_pattern
69+
end
6570

6671
def_node_matcher :shared_context, SharedGroups::CONTEXT.block_pattern
6772
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
@@ -91,17 +91,15 @@ module Examples
9191
end
9292

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

106104
module Scopes
107105
ALL = SelectorSet.new(
@@ -131,16 +129,6 @@ module Expectations
131129
module Runners
132130
ALL = SelectorSet.new(%i[to to_not not_to])
133131
end
134-
135-
ALL =
136-
ExampleGroups::ALL +
137-
SharedGroups::ALL +
138-
Examples::ALL +
139-
Hooks::ALL +
140-
Helpers::ALL +
141-
Subject::ALL +
142-
Expectations::ALL +
143-
Runners::ALL
144132
end
145133
end
146134
end

lib/rubocop/rspec/language/node_pattern.rb

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,35 @@ module NodePattern
2020

2121
def_node_matcher :example?, Examples::ALL.block_pattern
2222

23-
def_node_matcher :hook?, Hooks::ALL.block_pattern
24-
2523
def_node_matcher :let?, Helpers::ALL.block_or_block_pass_pattern
2624

2725
def_node_matcher :subject?, Subject::ALL.block_pattern
26+
27+
def_runtime_node_matcher :hook? do
28+
hook_selectors.block_pattern
29+
end
30+
31+
def hook_selectors
32+
custom_method_names = config
33+
.for_all_cops
34+
.fetch('RSpec', {})
35+
.fetch('Language', {})
36+
.fetch('Hooks', [])
37+
.map(&:to_sym)
38+
39+
SelectorSet.new(Hooks::BUILT_IN_METHOD_NAMES + custom_method_names)
40+
end
41+
42+
def all_selectors
43+
ExampleGroups::ALL +
44+
SharedGroups::ALL +
45+
Examples::ALL +
46+
hook_selectors +
47+
Helpers::ALL +
48+
Subject::ALL +
49+
Expectations::ALL +
50+
Runners::ALL
51+
end
2852
end
2953
end
3054
end

0 commit comments

Comments
 (0)