cql 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/lib/cql.rb +71 -63
- data/lib/dsl.rb +110 -110
- data/lib/feature_filters.rb +88 -72
- data/lib/map_reduce.rb +104 -40
- data/lib/sso_filters.rb +81 -72
- data/spec/filter_feature_dsl_spec.rb +284 -486
- data/spec/filter_sso_spec.rb +161 -288
- data/spec/line_count_filterable_specs.rb +73 -0
- data/spec/line_filterable_specs.rb +40 -0
- data/spec/map_reduce_spec.rb +132 -132
- data/spec/multiple_queries_spec.rb +27 -0
- data/spec/name_filterable_specs.rb +40 -0
- data/spec/select_feature_dsl_spec.rb +191 -50
- data/spec/select_scen_outline_dsl_spec.rb +323 -126
- data/spec/select_scenario_dsl_spec.rb +197 -73
- data/spec/spec_helper.rb +27 -0
- data/spec/tag_filterable_specs.rb +106 -0
- metadata +54 -37
- data/spec/unit_spec.rb +0 -22
data/lib/map_reduce.rb
CHANGED
@@ -1,40 +1,104 @@
|
|
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
|
-
end
|
26
|
-
|
27
|
-
def self.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
1
|
+
require_relative "dsl"
|
2
|
+
require_relative "feature_filters"
|
3
|
+
require_relative "sso_filters"
|
4
|
+
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
module CQL
|
8
|
+
QUERY_VALUES = %w(name uri line description type steps id tags examples)
|
9
|
+
|
10
|
+
class MapReduce
|
11
|
+
|
12
|
+
def self.name(data)
|
13
|
+
data = data.dup
|
14
|
+
data.map { |element| element.name }
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.uri(data)
|
18
|
+
data = data.dup
|
19
|
+
data.map { |element| element.parent_element.path }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.description(data)
|
23
|
+
data = data.dup
|
24
|
+
data.map { |element| element.description.join("\n") }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.tags(data)
|
28
|
+
data = data.dup
|
29
|
+
data.map { |element| element.raw_element['tags'] }
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.line(data)
|
33
|
+
data = data.dup
|
34
|
+
data.map { |element| element.source_line }
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.examples(data)
|
38
|
+
data = data.dup
|
39
|
+
data.map { |element| element.examples.collect { |example| example.raw_element } }
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.steps(data)
|
43
|
+
data = data.dup
|
44
|
+
data.map { |element| element.steps.collect { |step| step.raw_element } }
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.type(data)
|
48
|
+
data = data.dup
|
49
|
+
data.map do |element|
|
50
|
+
element_class = element.class.to_s[/::.*$/].gsub(':', '')
|
51
|
+
|
52
|
+
case element_class
|
53
|
+
when 'Outline'
|
54
|
+
type = 'scenario_outline'
|
55
|
+
when 'Scenario'
|
56
|
+
type = 'scenario'
|
57
|
+
else
|
58
|
+
raise "Unknown class: #{element_class}"
|
59
|
+
end
|
60
|
+
|
61
|
+
type
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.id(data)
|
66
|
+
data = data.dup
|
67
|
+
data.map { |element| element.raw_element['id'] }
|
68
|
+
end
|
69
|
+
|
70
|
+
%w(all everything complete).each do |method_name|
|
71
|
+
define_singleton_method(method_name) { |input| input }
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.step_lines input
|
75
|
+
input = [input] if input.class != Array
|
76
|
+
steps(input).map do |scen|
|
77
|
+
scen.map { |line| line['keyword'] + line['name'] }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.feature_children input, args
|
82
|
+
results = []
|
83
|
+
|
84
|
+
input.each do |feature|
|
85
|
+
feature.contains.each do |element|
|
86
|
+
|
87
|
+
case args['what']
|
88
|
+
when 'scenario'
|
89
|
+
results.push element if element.class.to_s[/::.*$/].gsub(':', '') == 'Scenario'
|
90
|
+
when 'scenario_outline'
|
91
|
+
results.push element if element.class.to_s[/::.*$/].gsub(':', '') == 'Outline'
|
92
|
+
else
|
93
|
+
raise "Unknown type: #{args['what']}"
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
results
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
data/lib/sso_filters.rb
CHANGED
@@ -1,73 +1,82 @@
|
|
1
|
-
module CQL
|
2
|
-
|
3
|
-
class SsoTagCountFilter < Filter
|
4
|
-
def execute input
|
5
|
-
input.each_with_index do |feature, index|
|
6
|
-
filtered_elements= feature
|
7
|
-
sso
|
8
|
-
end
|
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
|
-
result
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
1
|
+
module CQL
|
2
|
+
|
3
|
+
class SsoTagCountFilter < Filter
|
4
|
+
def execute input
|
5
|
+
input.each_with_index do |feature, index|
|
6
|
+
filtered_elements= feature.tests.find_all do |sso|
|
7
|
+
sso.tags.size.send(comparison.operator, comparison.amount)
|
8
|
+
end
|
9
|
+
|
10
|
+
input[index].tests = filtered_elements
|
11
|
+
end
|
12
|
+
|
13
|
+
input
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class SsoTagFilter < TagFilter
|
18
|
+
def execute input
|
19
|
+
input.each_with_index do |feature, index|
|
20
|
+
features_with_contents_filtered = feature.tests.find_all do |sso|
|
21
|
+
has_tags(sso.raw_element['tags'], tags)
|
22
|
+
end
|
23
|
+
|
24
|
+
input[index].tests = features_with_contents_filtered
|
25
|
+
end
|
26
|
+
|
27
|
+
input
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class SsoLineCountFilter < Filter
|
32
|
+
def execute input
|
33
|
+
input.each_with_index do |feature, index|
|
34
|
+
filtered_elements = feature.tests.find_all do |sso|
|
35
|
+
sso.steps.size.send(comparison.operator, comparison.amount)
|
36
|
+
end
|
37
|
+
|
38
|
+
input[index].tests = filtered_elements
|
39
|
+
end
|
40
|
+
|
41
|
+
input
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class LineFilter
|
46
|
+
attr_reader :line
|
47
|
+
|
48
|
+
def initialize line
|
49
|
+
@line = line
|
50
|
+
end
|
51
|
+
|
52
|
+
def execute input
|
53
|
+
input.each_with_index do |feature, index|
|
54
|
+
filtered_elements = feature.tests.find_all do |sso|
|
55
|
+
raw_step_lines = sso.steps.map { |sl| sl.base }
|
56
|
+
result = nil
|
57
|
+
|
58
|
+
if line.class == String
|
59
|
+
result = raw_step_lines.include? line
|
60
|
+
elsif line.class == Regexp
|
61
|
+
result = filter_by_regexp(raw_step_lines)
|
62
|
+
end
|
63
|
+
|
64
|
+
result
|
65
|
+
end
|
66
|
+
|
67
|
+
input[index].tests = filtered_elements
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def filter_by_regexp(raw_step_lines)
|
72
|
+
result = raw_step_lines.find { |l| l =~line }
|
73
|
+
if result.class == String
|
74
|
+
result = result.size > 0
|
75
|
+
else
|
76
|
+
result = false
|
77
|
+
end
|
78
|
+
result
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
73
82
|
end
|
@@ -1,486 +1,284 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
describe
|
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
|
-
end
|
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
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
}.each do |number, expected|
|
287
|
-
it "should filter features by the number of tags with the 'tc_lte' operator for count of #{number}" do
|
288
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/b"
|
289
|
-
|
290
|
-
result = gs.query do
|
291
|
-
select name
|
292
|
-
from features
|
293
|
-
with tc lte number
|
294
|
-
end
|
295
|
-
|
296
|
-
result.should == expected
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
{
|
301
|
-
0=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
|
302
|
-
1=>[{"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
|
303
|
-
2=>{"name"=> "f3_3_tags"},
|
304
|
-
3=>[],
|
305
|
-
4=>[]
|
306
|
-
|
307
|
-
}.each do |number, expected|
|
308
|
-
it "should filter features by the number of tags with the 'tc_gt' operator for count of #{number}" do
|
309
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/b"
|
310
|
-
|
311
|
-
result = gs.query do
|
312
|
-
select name
|
313
|
-
from features
|
314
|
-
with tc gt number
|
315
|
-
end
|
316
|
-
|
317
|
-
result.should == expected
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
{
|
322
|
-
0=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
|
323
|
-
1=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
|
324
|
-
2=>[{"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
|
325
|
-
3=>{"name"=> "f3_3_tags"},
|
326
|
-
4=>[],
|
327
|
-
5=>[]
|
328
|
-
|
329
|
-
}.each do |number, expected|
|
330
|
-
it "should filter features by the number of tags with the 'tc_gte' operator for count of #{number}" do
|
331
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/b"
|
332
|
-
|
333
|
-
result = gs.query do
|
334
|
-
select name
|
335
|
-
from features
|
336
|
-
with tc gte number
|
337
|
-
end
|
338
|
-
|
339
|
-
result.should == expected
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
end
|
344
|
-
|
345
|
-
describe 'scenario outline count functions' do
|
346
|
-
{
|
347
|
-
2=>[{"name"=> "f1_4_scenarios_5_so"}, {"name"=> "f2_7_scenarios_2_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
348
|
-
3=>[{"name"=> "f1_4_scenarios_5_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
349
|
-
4=>{"name"=> "f1_4_scenarios_5_so"},
|
350
|
-
7=>[]
|
351
|
-
|
352
|
-
}.each do |number, expected|
|
353
|
-
it "soc_gte filter should filter scenarios for input '#{number}'" do
|
354
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
|
355
|
-
|
356
|
-
result = gs.query do
|
357
|
-
select name
|
358
|
-
from features
|
359
|
-
with soc gte number
|
360
|
-
end
|
361
|
-
|
362
|
-
result.should == expected
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
{
|
367
|
-
7=>[{"name"=> "f1_4_scenarios_5_so"}, {"name"=> "f2_7_scenarios_2_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
368
|
-
5=>[{"name"=> "f2_7_scenarios_2_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
369
|
-
4=>[{"name"=> "f2_7_scenarios_2_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
370
|
-
|
371
|
-
}.each do |number, expected|
|
372
|
-
it "soc_lt filter should filter scenarios for input '#{number}'" do
|
373
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
|
374
|
-
result = gs.query do
|
375
|
-
select name
|
376
|
-
from features
|
377
|
-
with soc lt number
|
378
|
-
end
|
379
|
-
|
380
|
-
result.should == expected
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
|
385
|
-
{
|
386
|
-
7=>[{"name"=> "f1_4_scenarios_5_so"}, {"name"=>"f2_7_scenarios_2_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
387
|
-
5=>[{"name"=> "f1_4_scenarios_5_so"}, {"name"=>"f2_7_scenarios_2_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
388
|
-
4=>[{"name"=> "f2_7_scenarios_2_so"}, {"name"=> "f3_2_scenarios_3_so"}],
|
389
|
-
}.each do |num, expected|
|
390
|
-
it "should filter based on the number of scenarios for soc_lte with input '#{num}'" do
|
391
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
|
392
|
-
|
393
|
-
result = gs.query do
|
394
|
-
select name
|
395
|
-
from features
|
396
|
-
with soc lte num
|
397
|
-
end
|
398
|
-
|
399
|
-
result.should == expected
|
400
|
-
end
|
401
|
-
end
|
402
|
-
end
|
403
|
-
|
404
|
-
|
405
|
-
describe 'filter features by name' do
|
406
|
-
it 'should filter by name' do
|
407
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/scenario/tagged_features"
|
408
|
-
|
409
|
-
result = gs.query do
|
410
|
-
select name
|
411
|
-
from features
|
412
|
-
with name 'Test2 Feature'
|
413
|
-
end
|
414
|
-
|
415
|
-
result.should == {"name"=> "Test2 Feature"}
|
416
|
-
end
|
417
|
-
|
418
|
-
it 'should filter by name regexp' do
|
419
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/scenario/tagged_features"
|
420
|
-
|
421
|
-
result = gs.query do
|
422
|
-
select name
|
423
|
-
from features
|
424
|
-
with name /Test2 Feature/
|
425
|
-
end
|
426
|
-
|
427
|
-
result.should == {"name"=> "Test2 Feature"}
|
428
|
-
|
429
|
-
result = gs.query do
|
430
|
-
select name
|
431
|
-
from features
|
432
|
-
with name /Feature/
|
433
|
-
end
|
434
|
-
|
435
|
-
result.size.should == 3
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
describe 'filter features by tag' do
|
440
|
-
it 'should filter by a single tag' do
|
441
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/scenario/tagged_features"
|
442
|
-
|
443
|
-
result = gs.query do
|
444
|
-
select name
|
445
|
-
from features
|
446
|
-
with tags '@one'
|
447
|
-
end
|
448
|
-
|
449
|
-
result.should == [{"name"=> "Test Feature"}, {"name"=>"Test3 Feature"}]
|
450
|
-
|
451
|
-
result = gs.query do
|
452
|
-
select name
|
453
|
-
from features
|
454
|
-
with tags '@two'
|
455
|
-
end
|
456
|
-
|
457
|
-
result.should == [{"name"=> "Test2 Feature"}, {"name"=>"Test3 Feature"}]
|
458
|
-
end
|
459
|
-
|
460
|
-
it 'should filter by multiple filters' do
|
461
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/scenario/tagged_features"
|
462
|
-
|
463
|
-
result = gs.query do
|
464
|
-
select name
|
465
|
-
from features
|
466
|
-
with tags '@two'
|
467
|
-
with tags '@one'
|
468
|
-
end
|
469
|
-
|
470
|
-
result.should == {"name"=>"Test3 Feature"}
|
471
|
-
end
|
472
|
-
|
473
|
-
it 'should filter by a multiple tags' do
|
474
|
-
gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/scenario/tagged_features"
|
475
|
-
|
476
|
-
result = gs.query do
|
477
|
-
select name
|
478
|
-
from features
|
479
|
-
with tags '@one', '@two'
|
480
|
-
end
|
481
|
-
|
482
|
-
result.should == {"name"=>"Test3 Feature"}
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "feature filters (with)" do
|
4
|
+
describe 'scenario outline and scenario count functions (ssoc)' do
|
5
|
+
it 'should filter based on ssoc_gt' do
|
6
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
7
|
+
|
8
|
+
expected_results = {5 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}]}
|
9
|
+
|
10
|
+
expected_results.each do |number, expected|
|
11
|
+
result = gs.query do
|
12
|
+
select name
|
13
|
+
from features
|
14
|
+
with ssoc gt number
|
15
|
+
end
|
16
|
+
|
17
|
+
expect(result).to eq(expected)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should filter based on ssoc_gte' do
|
22
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
23
|
+
|
24
|
+
expected_results = {1 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
25
|
+
5 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
26
|
+
9 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}],
|
27
|
+
10 => []}
|
28
|
+
|
29
|
+
expected_results.each do |number, expected|
|
30
|
+
result = gs.query do
|
31
|
+
select name
|
32
|
+
from features
|
33
|
+
with ssoc gte number
|
34
|
+
end
|
35
|
+
|
36
|
+
expect(result).to eq(expected)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should filter based on ssoc_lt' do
|
41
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
42
|
+
|
43
|
+
expected_results = {10 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
44
|
+
9 => [{"name" => "f3_2_scenarios_3_so"}],
|
45
|
+
3 => []}
|
46
|
+
|
47
|
+
expected_results.each do |number, expected|
|
48
|
+
result = gs.query do
|
49
|
+
select name
|
50
|
+
from features
|
51
|
+
with ssoc lt number
|
52
|
+
end
|
53
|
+
|
54
|
+
expect(result).to eq(expected)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should filter based on ssoc_lte' do
|
59
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
60
|
+
|
61
|
+
expected_results = {10 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
62
|
+
9 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
63
|
+
5 => [{"name" => "f3_2_scenarios_3_so"}],
|
64
|
+
4 => []}
|
65
|
+
|
66
|
+
expected_results.each do |number, expected|
|
67
|
+
result = gs.query do
|
68
|
+
select name
|
69
|
+
from features
|
70
|
+
with ssoc lte number
|
71
|
+
end
|
72
|
+
|
73
|
+
expect(result).to eq(expected)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
describe 'scenario count functions (sc)' do
|
81
|
+
it 'should filter based on sc_gt' do
|
82
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
83
|
+
|
84
|
+
expected_results = {2 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}]}
|
85
|
+
|
86
|
+
expected_results.each do |number, expected|
|
87
|
+
result = gs.query do
|
88
|
+
select name
|
89
|
+
from features
|
90
|
+
with sc gt number
|
91
|
+
end
|
92
|
+
|
93
|
+
expect(result).to eq(expected)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should filter based on sc_gte' do
|
98
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
99
|
+
|
100
|
+
expected_results = {2 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
101
|
+
4 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}],
|
102
|
+
3 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}],
|
103
|
+
7 => [{"name" => "f2_7_scenarios_2_so"}]}
|
104
|
+
|
105
|
+
expected_results.each do |number, expected|
|
106
|
+
result = gs.query do
|
107
|
+
select name
|
108
|
+
from features
|
109
|
+
with sc gte number
|
110
|
+
end
|
111
|
+
|
112
|
+
expect(result).to eq(expected)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should filter based on sc_lt' do
|
117
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
118
|
+
|
119
|
+
expected_results = {
|
120
|
+
7 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
121
|
+
5 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
122
|
+
4 => [{"name" => "f3_2_scenarios_3_so"}]}
|
123
|
+
|
124
|
+
expected_results.each do |number, expected|
|
125
|
+
result = gs.query do
|
126
|
+
select name
|
127
|
+
from features
|
128
|
+
with sc lt number
|
129
|
+
end
|
130
|
+
|
131
|
+
expect(result).to eq(expected)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should filter based on sc_lte' do
|
136
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
137
|
+
|
138
|
+
expected_results = {7 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
139
|
+
5 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
140
|
+
4 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f3_2_scenarios_3_so"}]}
|
141
|
+
|
142
|
+
expected_results.each do |number, expected|
|
143
|
+
result = gs.query do
|
144
|
+
select name
|
145
|
+
from features
|
146
|
+
with sc lte number
|
147
|
+
end
|
148
|
+
|
149
|
+
expect(result).to eq(expected)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it_behaves_like 'a tag filterable target set', 'features', {:single_tag => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/tagged_features",
|
155
|
+
:expected_results => {'@one' => [{"name" => "Test Feature"}, {"name" => "Test3 Feature"}],
|
156
|
+
'@two' => [{"name" => "Test2 Feature"}, {"name" => "Test3 Feature"}]}},
|
157
|
+
:multiple_tags => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/tagged_features",
|
158
|
+
:expected_results => {['@one', '@two'] => [{"name" => "Test3 Feature"}]}},
|
159
|
+
:tc_lt => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/combined/b",
|
160
|
+
:expected_results => {0 => [],
|
161
|
+
1 => [],
|
162
|
+
2 => [{"name" => "f1_1_tag"}],
|
163
|
+
3 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}],
|
164
|
+
4 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}],
|
165
|
+
5 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}]}},
|
166
|
+
:tc_lte => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/combined/b",
|
167
|
+
:expected_results => {0 => [],
|
168
|
+
1 => [{"name" => "f1_1_tag"}],
|
169
|
+
2 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}],
|
170
|
+
3 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}],
|
171
|
+
4 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}]}},
|
172
|
+
:tc_gt => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/combined/b",
|
173
|
+
:expected_results => {0 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}],
|
174
|
+
1 => [{"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}],
|
175
|
+
2 => [{"name" => "f3_3_tags"}],
|
176
|
+
3 => [],
|
177
|
+
4 => []}},
|
178
|
+
:tc_gte => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/combined/b",
|
179
|
+
:expected_results => {0 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}],
|
180
|
+
1 => [{"name" => "f1_1_tag"}, {"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}],
|
181
|
+
2 => [{"name" => "f2_2_tags"}, {"name" => "f3_3_tags"}],
|
182
|
+
3 => [{"name" => "f3_3_tags"}],
|
183
|
+
4 => [],
|
184
|
+
5 => []}}
|
185
|
+
}
|
186
|
+
|
187
|
+
describe 'scenario outline count functions (soc)' do
|
188
|
+
it 'should filter based on soc_gt' do
|
189
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
190
|
+
|
191
|
+
expected_results = {2 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
192
|
+
5 => []}
|
193
|
+
|
194
|
+
expected_results.each do |number, expected|
|
195
|
+
result = gs.query do
|
196
|
+
select name
|
197
|
+
from features
|
198
|
+
with soc gt number
|
199
|
+
end
|
200
|
+
|
201
|
+
expect(result).to eq(expected)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'should filter based on soc_gte' do
|
206
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
207
|
+
|
208
|
+
expected_results = {2 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
209
|
+
3 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
210
|
+
4 => [{"name" => "f1_4_scenarios_5_so"}],
|
211
|
+
7 => []}
|
212
|
+
|
213
|
+
expected_results.each do |number, expected|
|
214
|
+
result = gs.query do
|
215
|
+
select name
|
216
|
+
from features
|
217
|
+
with soc gte number
|
218
|
+
end
|
219
|
+
|
220
|
+
expect(result).to eq(expected)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'should filter based on soc_lt' do
|
225
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
226
|
+
|
227
|
+
expected_results = {7 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
228
|
+
5 => [{"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
229
|
+
4 => [{"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}]}
|
230
|
+
|
231
|
+
|
232
|
+
expected_results.each do |number, expected|
|
233
|
+
result = gs.query do
|
234
|
+
select name
|
235
|
+
from features
|
236
|
+
with soc lt number
|
237
|
+
end
|
238
|
+
|
239
|
+
expect(result).to eq(expected)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should filter based on soc_lte' do
|
244
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/combined/a")
|
245
|
+
|
246
|
+
expected_results = {7 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
247
|
+
5 => [{"name" => "f1_4_scenarios_5_so"}, {"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}],
|
248
|
+
4 => [{"name" => "f2_7_scenarios_2_so"}, {"name" => "f3_2_scenarios_3_so"}]}
|
249
|
+
|
250
|
+
|
251
|
+
expected_results.each do |number, expected|
|
252
|
+
result = gs.query do
|
253
|
+
select name
|
254
|
+
from features
|
255
|
+
with soc lte number
|
256
|
+
end
|
257
|
+
|
258
|
+
expect(result).to eq(expected)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
it_behaves_like 'a name filterable target set', 'features', {:exact_name => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/tagged_features",
|
264
|
+
:expected_results => {'Test2 Feature' => [{"name" => "Test2 Feature"}]}},
|
265
|
+
:regexp => {:fixture_location => "#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/tagged_features",
|
266
|
+
:expected_results => {/Test2 Feature/ => [{"name" => "Test2 Feature"}],
|
267
|
+
/Feature/ => [{"name" => "Test Feature"}, {"name" => "Test2 Feature"}, {"name" => "Test3 Feature"}]}}
|
268
|
+
}
|
269
|
+
|
270
|
+
|
271
|
+
it 'should filter by multiple filters' do
|
272
|
+
gs = CQL::Repository.new("#{@feature_fixtures_directory}/scenario/tagged_features")
|
273
|
+
|
274
|
+
result = gs.query do
|
275
|
+
select name
|
276
|
+
from features
|
277
|
+
with tags '@two'
|
278
|
+
with tags '@one'
|
279
|
+
end
|
280
|
+
|
281
|
+
expect(result).to eq([{"name" => "Test3 Feature"}])
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|