cql 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/dsl.rb ADDED
@@ -0,0 +1,111 @@
1
+ require File.dirname(__FILE__) + "/map_reduce"
2
+ module CQL
3
+ module Dsl
4
+ #Select clause
5
+ def select *what
6
+ @what = what
7
+ end
8
+
9
+ (CQL::QUERY_VALUES + %w(all step_lines examples)).each do |method_name|
10
+ define_method(method_name) { |*args|
11
+ return method_name if args.size == 0
12
+ {method_name=>args}
13
+ }
14
+ end
15
+
16
+ alias :everything :all
17
+ alias :complete :all
18
+
19
+ def name *args
20
+ return 'name' if args.size == 0
21
+ CQL::NameFilter.new args[0]
22
+ end
23
+
24
+ def line *args
25
+ return 'line' if args.size == 0
26
+ CQL::LineFilter.new args.first
27
+ end
28
+
29
+ #from clause
30
+ def from where
31
+ @from = where
32
+ @data
33
+ end
34
+
35
+ %w(features scenario_outlines scenarios).each do |method_name|
36
+ define_method(method_name) { |*args|
37
+ return method_name if args.size == 0
38
+ {method_name=>args}
39
+ }
40
+ end
41
+
42
+ #with clause
43
+ def with filter
44
+ @data = filter.execute(@data)
45
+ end
46
+
47
+ class Comparison
48
+ attr_accessor :op, :amount
49
+
50
+ def initialize op, amount
51
+ @op = op
52
+ @amount = amount
53
+ end
54
+
55
+ def operator
56
+ {"lt"=>'<', 'lte'=>'<=', 'gt'=>'>', 'gte'=>'>='}[@op]
57
+ end
58
+
59
+ end
60
+
61
+ def tc comparison
62
+ if @from == 'features'
63
+ FeatureTagCountFilter.new('tc', comparison)
64
+ else
65
+ SsoTagCountFilter.new 'tc', comparison
66
+ end
67
+ end
68
+
69
+ def lc comparison
70
+ CQL::SsoLineCountFilter.new('lc', comparison)
71
+ end
72
+
73
+ def ssoc comparison
74
+ Filter.new('ssoc', comparison)
75
+ end
76
+
77
+ def sc comparison
78
+ Filter.new('sc', comparison)
79
+ end
80
+
81
+ def soc comparison
82
+ Filter.new('soc', comparison)
83
+ end
84
+
85
+ def gt amount
86
+ Comparison.new 'gt', amount
87
+ end
88
+
89
+ def gte amount
90
+ Comparison.new 'gte', amount
91
+ end
92
+
93
+ def lt amount
94
+ Comparison.new 'lt', amount
95
+ end
96
+
97
+ def lte amount
98
+ Comparison.new 'lte', amount
99
+ end
100
+
101
+ def tags *tags
102
+ return "tags" if tags.size == 0
103
+ if @from == 'features'
104
+ FeatureTagFilter.new tags
105
+ else
106
+ CQL::SsoTagFilter.new tags
107
+ end
108
+ end
109
+
110
+ end
111
+ end
@@ -0,0 +1,73 @@
1
+ module CQL
2
+ class NameFilter
3
+ attr_reader :name
4
+
5
+ def initialize name
6
+ @name = name
7
+ end
8
+
9
+ def execute input
10
+ if name.class == String
11
+ input = input.find_all { |feature| feature['name'] == name }
12
+ elsif name.class == Regexp
13
+ input = input.find_all { |feature| feature['name'] =~ name }
14
+ end
15
+ input
16
+ end
17
+ end
18
+
19
+ class Filter
20
+ attr_reader :type, :comparison
21
+
22
+ def initialize type, comparison
23
+ @type = type
24
+ @comparison = comparison
25
+ end
26
+
27
+ def full_type
28
+ {"sc"=>["Scenario"], "soc"=>["Scenario Outline"], "ssoc"=>["Scenario", "Scenario Outline"]}[@type]
29
+ end
30
+
31
+ def execute input
32
+ input.find_all do |feature|
33
+ size = feature['elements'].find_all { |e| full_type.include? e['keyword'] }.size
34
+ size.send(comparison.operator, comparison.amount)
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ class FeatureTagCountFilter < Filter
41
+ def execute input
42
+ input.find_all do |feature|
43
+ feature['tags'] && feature['tags'].size.send(comparison.operator, comparison.amount)
44
+ end
45
+ end
46
+ end
47
+
48
+ class TagFilter
49
+ attr_reader :tags
50
+
51
+ def initialize tags
52
+ @tags = tags
53
+ end
54
+
55
+ def has_tags given, search
56
+ return false if given == nil
57
+ search.count do |tag_for_search|
58
+ given.map { |t| t["name"] }.include?(tag_for_search)
59
+ end ==search.size
60
+ end
61
+ end
62
+
63
+ class FeatureTagFilter < TagFilter
64
+ def initialize tags
65
+ super tags
66
+ end
67
+
68
+ def execute input
69
+ input.find_all { |feature| has_tags feature['tags'], tags }
70
+ end
71
+ end
72
+
73
+ end
data/lib/map_reduce.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'set'
2
+ require File.dirname(__FILE__) + "/dsl"
3
+ require File.dirname(__FILE__) + "/feature_filters"
4
+ require File.dirname(__FILE__) + "/sso_filters"
5
+ module CQL
6
+ QUERY_VALUES = %w(name uri line description type steps id tags examples)
7
+
8
+ class MapReduce
9
+ CQL::QUERY_VALUES.each do |property|
10
+ define_singleton_method(property) do |input|
11
+ input = [input] if input.class != Array
12
+ input.map { |a| a[property] }
13
+ end
14
+ end
15
+
16
+ %w(all everything complete).each do |method_name|
17
+ define_singleton_method(method_name) { |input| input }
18
+ end
19
+
20
+ def self.step_lines input
21
+ input = [input] if input.class != Array
22
+ steps(input).map do |scen|
23
+ scen.map { |line| line['keyword'] + line['name'] }
24
+ end
25
+ end
26
+
27
+ def self.feature_children input, args
28
+ results = []
29
+ input = filter_features(input, 'feature'=>args['feature']) if args.has_key?('feature')
30
+ input.each do |feature|
31
+ feature['elements'].each do |element|
32
+ results.push element if element['type'] == args['what']
33
+ end
34
+ end
35
+ results
36
+ end
37
+
38
+ end
39
+
40
+ end
data/lib/repo.rb ADDED
@@ -0,0 +1,58 @@
1
+ require 'gherkin/parser/parser'
2
+ require 'gherkin/formatter/json_formatter'
3
+ require 'stringio'
4
+ require File.dirname(__FILE__) + "/dsl"
5
+
6
+ module CQL
7
+
8
+ class Query
9
+ include Dsl
10
+ attr_reader :data, :what
11
+
12
+ def format_to_ary_of_hsh data
13
+ result = Array.new(data.size).map{ |e| {} }
14
+ @what.each do |w|
15
+ CQL::MapReduce.send(w, data).each_with_index { |e, i| result[i][w]=e }
16
+ end
17
+ result.size == 1 ? result.first : result
18
+ end
19
+
20
+ def initialize features, &block
21
+ @data = features
22
+ @data = self.instance_eval(&block)
23
+
24
+ #getting the children of features
25
+ @data= CQL::MapReduce.feature_children(@data, 'what'=>@from[0, @from.size-1]) if @from != "features"
26
+
27
+ @data= format_to_ary_of_hsh(@data)
28
+ end
29
+ end
30
+
31
+
32
+ class Repository
33
+ attr_reader :parsed_feature_files
34
+
35
+ def initialize features_home_dir
36
+ @parsed_feature_files = load_features list_features features_home_dir
37
+ end
38
+
39
+ def query &block
40
+ Query.new(parsed_feature_files.clone, &block).data
41
+ end
42
+
43
+ private
44
+ def list_features base_dir
45
+ Dir.glob(base_dir + "/**/*.feature")
46
+ end
47
+
48
+ def load_features sources
49
+ io = StringIO.new
50
+ formatter = Gherkin::Formatter::JSONFormatter.new(io)
51
+ parser = Gherkin::Parser::Parser.new(formatter)
52
+ sources.each { |s| parser.parse(IO.read(s), s, 0) }
53
+ formatter.done
54
+ JSON.parse(io.string)
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,73 @@
1
+ module CQL
2
+
3
+ class SsoTagCountFilter < Filter
4
+ def execute input
5
+ input.each_with_index do |feature, index|
6
+ filtered_elements= feature['elements'].find_all do |sso|
7
+ sso['tags'].size.send(comparison.operator, comparison.amount)
8
+ end
9
+ input[index]['elements'] = filtered_elements
10
+ end
11
+ input
12
+ end
13
+ end
14
+
15
+ class SsoTagFilter < TagFilter
16
+ def execute input
17
+ input.each_with_index do |feature, index|
18
+ features_with_contents_filtered = feature['elements'].find_all do |sso|
19
+ has_tags(sso['tags'], tags)
20
+ end
21
+ input[index]['elements'] = features_with_contents_filtered
22
+ end
23
+ input
24
+ end
25
+ end
26
+
27
+ class SsoLineCountFilter < Filter
28
+ def execute input
29
+ input.each_with_index do |feature, index|
30
+ filtered_elements= feature['elements'].find_all do |sso|
31
+ sso['steps'].size.send(comparison.operator, comparison.amount)
32
+ end
33
+ input[index]['elements'] = filtered_elements
34
+ end
35
+ input
36
+ end
37
+ end
38
+
39
+ class LineFilter
40
+ attr_reader :line
41
+
42
+ def initialize line
43
+ @line = line
44
+ end
45
+
46
+ def execute input
47
+ input.each_with_index do |feature, index|
48
+ filtered_elements= feature['elements'].find_all do |sso|
49
+ raw_step_lines = sso['steps'].map { |sl| sl['name'] }
50
+ result = nil
51
+ if line.class == String
52
+ result = raw_step_lines.include? line
53
+ elsif line.class == Regexp
54
+ result = filter_by_regexp(raw_step_lines)
55
+ end
56
+ result
57
+ end
58
+ input[index]['elements'] = filtered_elements
59
+ end
60
+ end
61
+
62
+ def filter_by_regexp(raw_step_lines)
63
+ result = raw_step_lines.find { |l| l =~line }
64
+ if result.class == String
65
+ result = result.size > 0
66
+ else
67
+ result = false
68
+ end
69
+ result
70
+ end
71
+ end
72
+
73
+ end
@@ -1,486 +1,486 @@
1
- require 'rspec'
2
- require File.dirname(__FILE__) + "/../lib/repo"
3
-
4
- describe "cql" do
5
-
6
- describe 'scenario outline and scenario count functions' do
7
- it 'should filter based on the number of scenarios for ssoc_gt' do
8
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
9
-
10
- result = gs.query do
11
- select name
12
- from features
13
- with ssoc gt 5
14
- end
15
-
16
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
17
- {"name"=> "f2_7_scenarios_2_so"}]
18
- end
19
-
20
- it 'should filter based on the number of scenario outlines for ssoc_gte' do
21
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
22
-
23
- result = gs.query do
24
- select name
25
- from features
26
- with ssoc gte 5
27
- end
28
-
29
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
30
- {"name"=> "f2_7_scenarios_2_so"},
31
- {"name"=> "f3_2_scenarios_3_so"}]
32
-
33
- result = gs.query do
34
- select name
35
- from features
36
- with ssoc gte 9
37
- end
38
-
39
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
40
- {"name"=> "f2_7_scenarios_2_so"}]
41
-
42
- result = gs.query do
43
- select name
44
- from features
45
- with soc gte 1
46
- end
47
-
48
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
49
- {"name"=> "f2_7_scenarios_2_so"},
50
- {"name"=> "f3_2_scenarios_3_so"}]
51
-
52
- result = gs.query do
53
- select name
54
- from features
55
- with soc gte 10
56
- end
57
-
58
- result.should == []
59
- end
60
-
61
- it 'should filter based on the number of scenarios for ssoc_lt' do
62
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
63
-
64
- result = gs.query do
65
- select name
66
- from features
67
- with ssoc lt 10
68
- end
69
-
70
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
71
- {"name"=> "f2_7_scenarios_2_so"},
72
- {"name"=> "f3_2_scenarios_3_so"}]
73
-
74
- result = gs.query do
75
- select name
76
- from features
77
- with ssoc lt 9
78
- end
79
-
80
- result.should == {"name"=> "f3_2_scenarios_3_so"}
81
-
82
- result = gs.query do
83
- select name
84
- from features
85
- with ssoc lt 3
86
- end
87
-
88
- result.should == []
89
- end
90
-
91
- it 'should filter based on the number of scenarios for ssoc_lte' do
92
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
93
-
94
- result = gs.query do
95
- select name
96
- from features
97
- with ssoc lte 10
98
- end
99
-
100
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
101
- {"name"=>"f2_7_scenarios_2_so"},
102
- {"name"=> "f3_2_scenarios_3_so"}]
103
-
104
- result = gs.query do
105
- select name
106
- from features
107
- with ssoc lte 9
108
- end
109
-
110
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
111
- {"name"=>"f2_7_scenarios_2_so"},
112
- {"name"=> "f3_2_scenarios_3_so"}]
113
-
114
- result = gs.query do
115
- select name
116
- from features
117
- with ssoc lte 5
118
- end
119
-
120
- result.should == {"name"=> "f3_2_scenarios_3_so"}
121
-
122
-
123
- result = gs.query do
124
- select name
125
- from features
126
- with ssoc lte 4
127
- end
128
-
129
- result.should == []
130
- end
131
-
132
- end
133
-
134
-
135
- describe 'scenario count functions' do
136
- it 'should filter based on the number of scenarios for sc_gt' do
137
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
138
-
139
- result = gs.query do
140
- select name
141
- from features
142
- with sc gt 2
143
- end
144
-
145
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
146
- {"name"=> "f2_7_scenarios_2_so"}]
147
- end
148
-
149
- it 'should filter based on the number of scenarios for sc_gte' do
150
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
151
-
152
- result = gs.query do
153
- select name
154
- from features
155
- with sc gte 2
156
- end
157
-
158
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
159
- {"name"=> "f2_7_scenarios_2_so"},
160
- {"name"=> "f3_2_scenarios_3_so"}]
161
-
162
- result = gs.query do
163
- select name
164
- from features
165
- with sc gte 4
166
- end
167
-
168
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
169
- {"name"=> "f2_7_scenarios_2_so"}]
170
-
171
- result = gs.query do
172
- select name
173
- from features
174
- with sc gte 3
175
- end
176
-
177
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
178
- {"name"=> "f2_7_scenarios_2_so"}]
179
-
180
- result = gs.query do
181
- select name
182
- from features
183
- with sc gte 7
184
- end
185
-
186
- result.should == {"name"=> "f2_7_scenarios_2_so"}
187
- end
188
-
189
- it 'should filter based on the number of scenarios for sc_lt' do
190
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
191
-
192
- result = gs.query do
193
- select name
194
- from features
195
- with sc lt 7
196
- end
197
-
198
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
199
- {"name"=> "f3_2_scenarios_3_so"}]
200
-
201
- result = gs.query do
202
- select name
203
- from features
204
- with sc lt 5
205
- end
206
-
207
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
208
- {"name"=> "f3_2_scenarios_3_so"}]
209
-
210
- result = gs.query do
211
- select name
212
- from features
213
- with sc lt 4
214
- end
215
-
216
- result.should == {"name"=> "f3_2_scenarios_3_so"}
217
- end
218
-
219
- it 'should filter based on the number of scenarios for sc_lte' do
220
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
221
-
222
- result = gs.query do
223
- select name
224
- from features
225
- with sc lte 7
226
- end
227
-
228
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
229
- {"name"=>"f2_7_scenarios_2_so"},
230
- {"name"=> "f3_2_scenarios_3_so"}]
231
-
232
- result = gs.query do
233
- select name
234
- from features
235
- with sc lte 5
236
- end
237
-
238
- result.should == [{"name"=> "f1_4_scenarios_5_so"},
239
- {"name"=> "f3_2_scenarios_3_so"}]
240
-
241
- result = gs.query do
242
- select name
243
- from features
244
- with sc lte 4
245
- end
246
-
247
- result.should == [{"name"=> "f1_4_scenarios_5_so"}, {"name"=> "f3_2_scenarios_3_so"}]
248
- end
249
-
250
- it 'should filter on the number of tags on a feature' do
251
-
252
- end
253
- end
254
-
255
- describe 'filter by tag count' do
256
-
257
- {
258
- 0=>[],
259
- 1=>[],
260
- 2=>{"name"=> "f1_1_tag"},
261
- 3=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}],
262
- 4=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
263
- 5=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}]
264
-
265
- }.each do |number, expected|
266
- it "should filter features by the number of tags with the 'tc_lt' operator for count of #{number}" do
267
- gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/b"
268
-
269
- result = gs.query do
270
- select name
271
- from features
272
- with tc lt number
273
- end
274
-
275
- result.should == expected
276
- end
277
- end
278
-
279
- {
280
- 0=>[],
281
- 1=>{"name"=> "f1_1_tag"},
282
- 2=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}],
283
- 3=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
284
- 4=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}]
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
-
1
+ require 'rspec'
2
+ require File.dirname(__FILE__) + "/../lib/repo"
3
+
4
+ describe "cql" do
5
+
6
+ describe 'scenario outline and scenario count functions' do
7
+ it 'should filter based on the number of scenarios for ssoc_gt' do
8
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
9
+
10
+ result = gs.query do
11
+ select name
12
+ from features
13
+ with ssoc gt 5
14
+ end
15
+
16
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
17
+ {"name"=> "f2_7_scenarios_2_so"}]
18
+ end
19
+
20
+ it 'should filter based on the number of scenario outlines for ssoc_gte' do
21
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
22
+
23
+ result = gs.query do
24
+ select name
25
+ from features
26
+ with ssoc gte 5
27
+ end
28
+
29
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
30
+ {"name"=> "f2_7_scenarios_2_so"},
31
+ {"name"=> "f3_2_scenarios_3_so"}]
32
+
33
+ result = gs.query do
34
+ select name
35
+ from features
36
+ with ssoc gte 9
37
+ end
38
+
39
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
40
+ {"name"=> "f2_7_scenarios_2_so"}]
41
+
42
+ result = gs.query do
43
+ select name
44
+ from features
45
+ with soc gte 1
46
+ end
47
+
48
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
49
+ {"name"=> "f2_7_scenarios_2_so"},
50
+ {"name"=> "f3_2_scenarios_3_so"}]
51
+
52
+ result = gs.query do
53
+ select name
54
+ from features
55
+ with soc gte 10
56
+ end
57
+
58
+ result.should == []
59
+ end
60
+
61
+ it 'should filter based on the number of scenarios for ssoc_lt' do
62
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
63
+
64
+ result = gs.query do
65
+ select name
66
+ from features
67
+ with ssoc lt 10
68
+ end
69
+
70
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
71
+ {"name"=> "f2_7_scenarios_2_so"},
72
+ {"name"=> "f3_2_scenarios_3_so"}]
73
+
74
+ result = gs.query do
75
+ select name
76
+ from features
77
+ with ssoc lt 9
78
+ end
79
+
80
+ result.should == {"name"=> "f3_2_scenarios_3_so"}
81
+
82
+ result = gs.query do
83
+ select name
84
+ from features
85
+ with ssoc lt 3
86
+ end
87
+
88
+ result.should == []
89
+ end
90
+
91
+ it 'should filter based on the number of scenarios for ssoc_lte' do
92
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
93
+
94
+ result = gs.query do
95
+ select name
96
+ from features
97
+ with ssoc lte 10
98
+ end
99
+
100
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
101
+ {"name"=>"f2_7_scenarios_2_so"},
102
+ {"name"=> "f3_2_scenarios_3_so"}]
103
+
104
+ result = gs.query do
105
+ select name
106
+ from features
107
+ with ssoc lte 9
108
+ end
109
+
110
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
111
+ {"name"=>"f2_7_scenarios_2_so"},
112
+ {"name"=> "f3_2_scenarios_3_so"}]
113
+
114
+ result = gs.query do
115
+ select name
116
+ from features
117
+ with ssoc lte 5
118
+ end
119
+
120
+ result.should == {"name"=> "f3_2_scenarios_3_so"}
121
+
122
+
123
+ result = gs.query do
124
+ select name
125
+ from features
126
+ with ssoc lte 4
127
+ end
128
+
129
+ result.should == []
130
+ end
131
+
132
+ end
133
+
134
+
135
+ describe 'scenario count functions' do
136
+ it 'should filter based on the number of scenarios for sc_gt' do
137
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
138
+
139
+ result = gs.query do
140
+ select name
141
+ from features
142
+ with sc gt 2
143
+ end
144
+
145
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
146
+ {"name"=> "f2_7_scenarios_2_so"}]
147
+ end
148
+
149
+ it 'should filter based on the number of scenarios for sc_gte' do
150
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
151
+
152
+ result = gs.query do
153
+ select name
154
+ from features
155
+ with sc gte 2
156
+ end
157
+
158
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
159
+ {"name"=> "f2_7_scenarios_2_so"},
160
+ {"name"=> "f3_2_scenarios_3_so"}]
161
+
162
+ result = gs.query do
163
+ select name
164
+ from features
165
+ with sc gte 4
166
+ end
167
+
168
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
169
+ {"name"=> "f2_7_scenarios_2_so"}]
170
+
171
+ result = gs.query do
172
+ select name
173
+ from features
174
+ with sc gte 3
175
+ end
176
+
177
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
178
+ {"name"=> "f2_7_scenarios_2_so"}]
179
+
180
+ result = gs.query do
181
+ select name
182
+ from features
183
+ with sc gte 7
184
+ end
185
+
186
+ result.should == {"name"=> "f2_7_scenarios_2_so"}
187
+ end
188
+
189
+ it 'should filter based on the number of scenarios for sc_lt' do
190
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
191
+
192
+ result = gs.query do
193
+ select name
194
+ from features
195
+ with sc lt 7
196
+ end
197
+
198
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
199
+ {"name"=> "f3_2_scenarios_3_so"}]
200
+
201
+ result = gs.query do
202
+ select name
203
+ from features
204
+ with sc lt 5
205
+ end
206
+
207
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
208
+ {"name"=> "f3_2_scenarios_3_so"}]
209
+
210
+ result = gs.query do
211
+ select name
212
+ from features
213
+ with sc lt 4
214
+ end
215
+
216
+ result.should == {"name"=> "f3_2_scenarios_3_so"}
217
+ end
218
+
219
+ it 'should filter based on the number of scenarios for sc_lte' do
220
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/a"
221
+
222
+ result = gs.query do
223
+ select name
224
+ from features
225
+ with sc lte 7
226
+ end
227
+
228
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
229
+ {"name"=>"f2_7_scenarios_2_so"},
230
+ {"name"=> "f3_2_scenarios_3_so"}]
231
+
232
+ result = gs.query do
233
+ select name
234
+ from features
235
+ with sc lte 5
236
+ end
237
+
238
+ result.should == [{"name"=> "f1_4_scenarios_5_so"},
239
+ {"name"=> "f3_2_scenarios_3_so"}]
240
+
241
+ result = gs.query do
242
+ select name
243
+ from features
244
+ with sc lte 4
245
+ end
246
+
247
+ result.should == [{"name"=> "f1_4_scenarios_5_so"}, {"name"=> "f3_2_scenarios_3_so"}]
248
+ end
249
+
250
+ it 'should filter on the number of tags on a feature' do
251
+
252
+ end
253
+ end
254
+
255
+ describe 'filter by tag count' do
256
+
257
+ {
258
+ 0=>[],
259
+ 1=>[],
260
+ 2=>{"name"=> "f1_1_tag"},
261
+ 3=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}],
262
+ 4=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
263
+ 5=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}]
264
+
265
+ }.each do |number, expected|
266
+ it "should filter features by the number of tags with the 'tc_lt' operator for count of #{number}" do
267
+ gs = CQL::Repository.new File.dirname(__FILE__) + "/../fixtures/features/combined/b"
268
+
269
+ result = gs.query do
270
+ select name
271
+ from features
272
+ with tc lt number
273
+ end
274
+
275
+ result.should == expected
276
+ end
277
+ end
278
+
279
+ {
280
+ 0=>[],
281
+ 1=>{"name"=> "f1_1_tag"},
282
+ 2=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}],
283
+ 3=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}],
284
+ 4=>[{"name"=> "f1_1_tag"}, {"name"=> "f2_2_tags"}, {"name"=> "f3_3_tags"}]
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
486
  end