-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathfilters.cr
238 lines (203 loc) · 6.47 KB
/
filters.cr
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
require "./item"
require "./example"
require "./context"
module Spec
module Item
# :nodoc:
def matches_pattern?(pattern : Regex) : Bool
!!(@description =~ pattern)
end
# :nodoc:
def matches_line?(line : Int32) : Bool
@line == line || @line <= line <= @end_line
end
# :nodoc:
def matches_locations?(locations : Hash(String, Array(Int32))) : Bool
lines = locations[file]?
!!(lines && lines.any? { |line| matches_line?(line) })
end
# :nodoc:
def matches_tags?(tags : Set(String)) : Bool
if t = @tags
tags.intersects?(t)
else
false
end
end
end
class RootContext
# :nodoc:
def run_filters(pattern = nil, line = nil, locations = nil, split_filter = nil, focus = nil, tags = nil, anti_tags = nil)
filter_by_pattern(pattern) if pattern
filter_by_line(line) if line
filter_by_locations(locations) if locations
filter_by_split(split_filter) if split_filter
filter_by_focus if focus
filter_by_tags(tags) if tags
filter_by_anti_tags(anti_tags) if anti_tags
end
# :nodoc:
def filter_by_pattern(pattern : Regex)
children.select!(&.filter_by_pattern(pattern))
end
# :nodoc:
def filter_by_line(line : Int32)
children.select!(&.filter_by_line(line))
end
# :nodoc:
def filter_by_locations(locations : Hash(String, Array(Int32)))
children.select!(&.filter_by_locations(locations))
end
# :nodoc:
def filter_by_focus
children.select!(&.filter_by_focus)
end
# :nodoc:
def filter_by_tags(tags : Set(String))
children.select!(&.filter_by_tags(tags))
end
# :nodoc:
def filter_by_anti_tags(anti_tags : Set(String))
children.select!(&.filter_by_anti_tags(anti_tags))
end
# :nodoc:
def filter_by_split(split_filter : SplitFilter)
children.select!(&.filter_by_split(split_filter))
end
end
class ExampleGroup
# :nodoc:
#
# Filters a context and its children by pattern.
# Returns `true` if the context matches the pattern, `false` otherwise.
def filter_by_pattern(pattern : Regex) : Bool
return true if matches_pattern?(pattern)
children.select!(&.filter_by_pattern(pattern))
!children.empty?
end
# :nodoc:
#
# Filters a context and its children by line.
# Returns `true` if the context matches the line, `false` otherwise.
def filter_by_line(line : Int32) : Bool
# If any children matches then we match too, but we filter children
if children.any? &.matches_line?(line)
children.select!(&.filter_by_line(line))
return true
end
# Otherwise check if we match. If we do it means the line is inside
# this context but outside a nested context or example, so then we
# have to run all contexts and examples inside ourselves.
if matches_line?(line)
return true
end
false
end
# :nodoc:
#
# Filters a context and its children by the given locations.
# Returns `true` if the context matches the locations, `false` otherwise.
def filter_by_locations(locations : Hash(String, Array(Int32))) : Bool
# If any children matches then we match too, but we filter children
if children.any? &.matches_locations?(locations)
children.select!(&.filter_by_locations(locations))
return true
end
# Otherwise check if we match. If we do it means the line is inside
# this context but outside a nested context or example, so then we
# have to run all contexts and examples inside ourselves.
if matches_locations?(locations)
return true
end
false
end
# :nodoc:
#
# Filters a context and its children that are marked as focus.
# Returns `true` if the context or any of its children have focus,
# `false` otherwise.
def filter_by_focus : Bool
return true if focus?
children.select!(&.filter_by_focus)
!children.empty?
end
# :nodoc:
#
# Filters a context and its children by the given tags.
# Returns `true` if the context matches the tags, `false` otherwise.
def filter_by_tags(tags : Set(String)) : Bool
return true if matches_tags?(tags)
children.select!(&.filter_by_tags(tags))
!children.empty?
end
# :nodoc:
#
# Filters a context and its children by the given anti-tags.
# Returns `false` if the context matches the anti_tags, `true` otherwise.
def filter_by_anti_tags(anti_tags : Set(String)) : Bool
return false if matches_tags?(anti_tags)
children.select!(&.filter_by_anti_tags(anti_tags))
!children.empty?
end
# :nodoc:
#
# Filters a context and its children by the given split filter
# Returns `true` if the context matches the filter, `false` otherwise.
def filter_by_split(split_filter : SplitFilter) : Bool
children.select!(&.filter_by_split(split_filter))
!children.empty?
end
end
class Example
# :nodoc:
#
# Returns `true` if the example matches the pattern,
# `false` otherwise.
def filter_by_pattern(pattern : Regex) : Bool
matches_pattern?(pattern)
end
# :nodoc:
#
# Returns `true` if the example is contained in the given line,
# `false` otherwise.
def filter_by_line(line : Int32) : Bool
matches_line?(line)
end
# :nodoc:
#
# Returns `true` if the example is contained in any of the given locations,
# `false` otherwise.
def filter_by_locations(locations : Hash(String, Array(Int32))) : Bool
matches_locations?(locations)
end
# :nodoc:
#
# Returns `true` if this example is marked as focus, `false` otherwise
def filter_by_focus : Bool
@focus
end
# :nodoc:
#
# Returns `true` if the example is tagged with any of the given tags,
# `false` otherwise.
def filter_by_tags(tags : Set(String)) : Bool
matches_tags?(tags)
end
# :nodoc:
#
# Returns `false` if the example is tagged with any of the given anti_tags,
# `true` otherwise.
def filter_by_anti_tags(anti_tags : Set(String)) : Bool
!matches_tags?(anti_tags)
end
@@example_counter = -1
# :nodoc:
#
# Returns `true` if the example is matches the given split filter,
# `false` otherwise.`
def filter_by_split(split_filter : SplitFilter) : Bool
@@example_counter += 1
@@example_counter % split_filter.quotient == split_filter.remainder
end
end
end