cql 0.1.0 → 0.1.0.1
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.
- data/lib/dsl.rb +64 -0
- data/lib/map_reduce.rb +139 -0
- data/lib/repo.rb +34 -0
- data/spec/filter_feature_dsl_spec.rb +486 -0
- data/spec/filter_sso_spec.rb +279 -0
- data/spec/map_reduce_spec.rb +132 -0
- data/spec/select_feature_dsl_spec.rb +50 -0
- data/spec/select_scen_outline_dsl_spec.rb +126 -0
- data/spec/select_scenario_dsl_spec.rb +73 -0
- data/spec/unit_spec.rb +22 -0
- metadata +21 -4
data/lib/dsl.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/map_reduce"
|
2
|
+
module CQL
|
3
|
+
DSL_KEYWORDS = %w(features scenario_outlines scenarios all step_lines examples name)
|
4
|
+
module Dsl
|
5
|
+
(CQL::QUERY_VALUES + CQL::DSL_KEYWORDS).each do |method_name|
|
6
|
+
define_method(method_name) { |*args|
|
7
|
+
return method_name if args.size == 0
|
8
|
+
{method_name=>args}
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
%w(sc_gt sc_gte sc_lt sc_lte soc_gt soc_gte soc_lt soc_lte ssoc_gt ssoc_gte ssoc_lt ssoc_lte tc_lt tc_lte tc_gt tc_gte lc_lt lc_lte lc_gt lc_gte).each do |meth|
|
13
|
+
define_method(meth) { |num| {meth=>num} }
|
14
|
+
end
|
15
|
+
|
16
|
+
alias :everything :all
|
17
|
+
alias :complete :all
|
18
|
+
|
19
|
+
def select *what
|
20
|
+
@what = what
|
21
|
+
end
|
22
|
+
|
23
|
+
def from where
|
24
|
+
@from = where
|
25
|
+
@data
|
26
|
+
end
|
27
|
+
|
28
|
+
def tags *tags
|
29
|
+
return "tags" if tags.size == 0
|
30
|
+
{'tags'=>tags}
|
31
|
+
end
|
32
|
+
|
33
|
+
def with filter
|
34
|
+
if filter.has_key? 'name'
|
35
|
+
@data = CQL::MapReduce.filter_features(@data, 'feature'=>filter['name'])
|
36
|
+
elsif @from == 'features'
|
37
|
+
filter.each { |k, v| @data = CQL::MapReduce.filter_features(@data, k=>v) }
|
38
|
+
elsif @from == 'scenarios'
|
39
|
+
filter.each { |k, v|
|
40
|
+
@data = CQL::MapReduce.filter_sso2(@data, k=>v)
|
41
|
+
}
|
42
|
+
end
|
43
|
+
@data
|
44
|
+
end
|
45
|
+
|
46
|
+
class Query
|
47
|
+
include Dsl
|
48
|
+
attr_reader :data, :what
|
49
|
+
|
50
|
+
def initialize features, &block
|
51
|
+
@data = features
|
52
|
+
@data = self.instance_eval(&block)
|
53
|
+
|
54
|
+
@data= CQL::MapReduce.filter_sso(@data, 'what'=>@from[0, @from.size-1]) if @from != "features"
|
55
|
+
result = Array.new(@data.size)
|
56
|
+
result = result.map {|e|{}}
|
57
|
+
@what.each do |w|
|
58
|
+
CQL::MapReduce.send(w, @data).each_with_index { |e, i| result[i][w]=e }
|
59
|
+
end
|
60
|
+
@data = result.size == 1 ? result.first : result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/map_reduce.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/dsl"
|
2
|
+
require 'set'
|
3
|
+
module CQL
|
4
|
+
QUERY_VALUES = %w(name uri line description type steps id tags examples)
|
5
|
+
|
6
|
+
class MapReduce
|
7
|
+
CQL::QUERY_VALUES.each do |property|
|
8
|
+
define_singleton_method(property) do |input|
|
9
|
+
input = [input] if input.class != Array
|
10
|
+
input.map { |a| a[property] }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
%w(all everything complete).each do |method_name|
|
15
|
+
define_singleton_method(method_name) { |input| input }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.step_lines input
|
19
|
+
input = [input] if input.class != Array
|
20
|
+
steps(input).map do |scen|
|
21
|
+
scen.map { |line| line['keyword'] + line['name'] }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.filter_features input, args
|
26
|
+
if args.has_key?('feature') && args['feature'][0].class == String
|
27
|
+
input = input.find_all { |feature| feature['name'] == args['feature'][0] }
|
28
|
+
elsif args.has_key?('feature') && args['feature'][0].class == Regexp
|
29
|
+
input = input.find_all { |feature| feature['name'] =~ args['feature'][0] }
|
30
|
+
end
|
31
|
+
|
32
|
+
%w(sc_gt sc_gte sc_lt sc_lte soc_gt soc_gte soc_lt soc_lte ssoc_gt ssoc_gte ssoc_lt ssoc_lte).each do |fn|
|
33
|
+
if args.has_key?(fn)
|
34
|
+
what, operator = fn.split "_"
|
35
|
+
desc = {"sc"=>["Scenario"], "soc"=>["Scenario Outline"], "ssoc"=>["Scenario", "Scenario Outline"]}
|
36
|
+
operator_map = {"lt"=>'<', 'lte'=>'<=', 'gt'=>'>', 'gte'=>'>='}
|
37
|
+
input = input.find_all do |feature|
|
38
|
+
size = feature['elements'].find_all { |e| desc[what].include? e['keyword'] }.size
|
39
|
+
size.send(operator_map[operator], args[fn])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
%w(tc_lt tc_lte tc_gt tc_gte).each do |fn|
|
45
|
+
what, operator = fn.split "_"
|
46
|
+
operator_map = {"lt"=>'<', 'lte'=>'<=', 'gt'=>'>', 'gte'=>'>='}
|
47
|
+
if args.has_key?(fn)
|
48
|
+
input = input.find_all do |feature|
|
49
|
+
feature['tags'] && feature['tags'].size.send(operator_map[operator], args[fn])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
input = input.find_all { |feature| has_tags feature['tags'], args['tags'] } if args.has_key? 'tags'
|
55
|
+
input
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.filter_sso input, args
|
59
|
+
results = []
|
60
|
+
input = filter_features(input, 'feature'=>args['feature']) if args.has_key?('feature')
|
61
|
+
input.each do |feature|
|
62
|
+
feature['elements'].each do |element|
|
63
|
+
results.push element if element['type'] == args['what']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
results
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.filter_sso2 input, args
|
70
|
+
%w(tc_lt tc_lte tc_gt tc_gte).each do |fn|
|
71
|
+
what, operator = fn.split "_"
|
72
|
+
operator_map = {"lt"=>'<', 'lte'=>'<=', 'gt'=>'>', 'gte'=>'>='}
|
73
|
+
if args.has_key?(fn)
|
74
|
+
input.each_with_index do |feature, index|
|
75
|
+
filtered_elements= feature['elements'].find_all do |sso|
|
76
|
+
sso['tags'].size.send(operator_map[operator], args[fn])
|
77
|
+
end
|
78
|
+
input[index]['elements'] = filtered_elements
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
%w(lc_lt lc_lte lc_gt lc_gte).each do |fn|
|
85
|
+
what, operator = fn.split "_"
|
86
|
+
operator_map = {"lt"=>'<', 'lte'=>'<=', 'gt'=>'>', 'gte'=>'>='}
|
87
|
+
if args.has_key?(fn)
|
88
|
+
input.each_with_index do |feature, index|
|
89
|
+
filtered_elements= feature['elements'].find_all do |sso|
|
90
|
+
sso['steps'].size.send(operator_map[operator], args[fn])
|
91
|
+
end
|
92
|
+
input[index]['elements'] = filtered_elements
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if args.has_key? 'line'
|
98
|
+
input.each_with_index do |feature, index|
|
99
|
+
filtered_elements= feature['elements'].find_all do |sso|
|
100
|
+
raw_step_lines = sso['steps'].map { |sl| sl['name'] }
|
101
|
+
line_to_match = args['line'].first
|
102
|
+
result = nil
|
103
|
+
if line_to_match.class == String
|
104
|
+
result = raw_step_lines.include? line_to_match
|
105
|
+
elsif line_to_match.class == Regexp
|
106
|
+
result = raw_step_lines.find { |line| line =~ line_to_match }
|
107
|
+
if result.class == String
|
108
|
+
result = result.size > 0
|
109
|
+
else
|
110
|
+
result = false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
result
|
114
|
+
end
|
115
|
+
input[index]['elements'] = filtered_elements
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
input
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.tag_set input
|
123
|
+
tags = Set.new
|
124
|
+
input.each do |feature|
|
125
|
+
feature['elements'].each do |element|
|
126
|
+
break if element['tags'] == nil
|
127
|
+
element['tags'].each { |tag| tags.add tag['name'] }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
tags.to_a
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.has_tags given, search
|
134
|
+
return false if given == nil
|
135
|
+
search.count { |tag_for_search| given.map { |t| t["name"] }.include?(tag_for_search) }==search.size
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
data/lib/repo.rb
ADDED
@@ -0,0 +1,34 @@
|
|
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
|
+
class Repository
|
8
|
+
include Dsl
|
9
|
+
attr_reader :parsed_feature_files
|
10
|
+
|
11
|
+
def initialize features_home_dir
|
12
|
+
@parsed_feature_files = load_features(list_features(features_home_dir))
|
13
|
+
end
|
14
|
+
|
15
|
+
def query &block
|
16
|
+
Query.new(parsed_feature_files.clone, &block).data
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def list_features base_dir
|
21
|
+
Dir.glob(base_dir + "/**/*.feature")
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_features sources
|
25
|
+
io = StringIO.new
|
26
|
+
formatter = Gherkin::Formatter::JSONFormatter.new(io)
|
27
|
+
parser = Gherkin::Parser::Parser.new(formatter)
|
28
|
+
sources.each { |s| parser.parse(IO.read(s), s, 0) }
|
29
|
+
formatter.done
|
30
|
+
JSON.parse(io.string)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +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
|
+
|
486
|
+
end
|