-
-
Notifications
You must be signed in to change notification settings - Fork 269
/
example_group.rb
73 lines (62 loc) · 2.05 KB
/
example_group.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# frozen_string_literal: true
module RuboCop
module RSpec
# Wrapper for RSpec example groups
class ExampleGroup < Concept
# Cop object may be passed into overriden constructor as additional param,
# so we can call predicate on cop itself and will have access to #config
# method in order to use configured language aliases for predicates.
# If no predicate_receiver passed - predicate will be called on
# ExampleGroup as if was before.
def initialize(node, predicate_receiver = self)
@predicate_receiver = predicate_receiver
super(node)
end
# @!method scope_change?(node)
#
# Detect if the node is an example group or shared example
#
# Selectors which indicate that we should stop searching
#
def_node_matcher :scope_change?, (
ExampleGroups::ALL + SharedGroups::ALL + Includes::ALL
).block_pattern
def lets
find_all_in_scope(node, :let?)
end
def subjects
find_all_in_scope(node, :subject?)
end
def examples
find_all_in_scope(node, :example?).map(&Example.public_method(:new))
end
def hooks
find_all_in_scope(node, :hook?).map(&Hook.public_method(:new))
end
private
attr_reader :predicate_receiver
# Recursively search for predicate within the current scope
#
# Searches node and halts when a scope change is detected
#
# @param node [RuboCop::Node] node to recursively search
# @param predicate [Symbol] method to call with node as argument
#
# @return [Array<RuboCop::Node>] discovered nodes
def find_all_in_scope(node, predicate)
node.each_child_node.flat_map do |child|
find_all(child, predicate)
end
end
def find_all(node, predicate)
if predicate_receiver.public_send(predicate, node)
[node]
elsif scope_change?(node) || example?(node)
[]
else
find_all_in_scope(node, predicate)
end
end
end
end
end