/
example_group.rb
107 lines (89 loc) · 2.32 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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# frozen_string_literal: true
module RuboCop
module RSpec
# Wrapper for RSpec example groups
class ExampleGroup < Concept
# @!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
lets_in_scope(node)
end
def subjects
subjects_in_scope(node)
end
def examples
examples_in_scope(node).map(&Example.public_method(:new))
end
def hooks
hooks_in_scope(node).map(&Hook.public_method(:new))
end
private
def subjects_in_scope(node)
node.each_child_node.flat_map do |child|
find_subjects(child)
end
end
def lets_in_scope(node)
node.each_child_node.flat_map do |child|
find_lets(child)
end
end
def find_subjects(node)
return [] if scope_change?(node)
if subject?(node)
[node]
else
subjects_in_scope(node)
end
end
def find_lets(node)
return [] if scope_change?(node)
if let?(node)
[node]
else
lets_in_scope(node)
end
end
def hooks_in_scope(node)
node.each_child_node.flat_map do |child|
find_hooks(child)
end
end
def find_hooks(node)
return [] if scope_change?(node) || example?(node)
if hook?(node)
[node]
else
hooks_in_scope(node)
end
end
def examples_in_scope(node, &blk)
node.each_child_node.flat_map do |child|
find_examples(child, &blk)
end
end
# Recursively search for examples within the current scope
#
# Searches node for examples and halts when a scope change is detected
#
# @param node [RuboCop::Node] node to recursively search for examples
#
# @return [Array<RuboCop::Node>] discovered example nodes
def find_examples(node)
return [] if scope_change?(node)
if example?(node)
[node]
else
examples_in_scope(node)
end
end
end
end
end