cql 0.1.7 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/cql.rb +62 -57
- data/lib/dsl.rb +110 -110
- data/lib/feature_filters.rb +72 -72
- data/lib/map_reduce.rb +39 -39
- data/lib/sso_filters.rb +72 -72
- data/spec/filter_feature_dsl_spec.rb +485 -485
- data/spec/filter_sso_spec.rb +287 -287
- data/spec/map_reduce_spec.rb +131 -131
- data/spec/select_feature_dsl_spec.rb +49 -49
- data/spec/select_scen_outline_dsl_spec.rb +125 -125
- data/spec/select_scenario_dsl_spec.rb +72 -72
- data/spec/unit_spec.rb +21 -21
- metadata +5 -5
data/lib/cql.rb
CHANGED
@@ -1,58 +1,63 @@
|
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
+
require 'find'
|
46
|
+
res = []
|
47
|
+
Find.find(base_dir) do |f|
|
48
|
+
res << f if f.match(/\.feature\Z/)
|
49
|
+
end
|
50
|
+
res
|
51
|
+
end
|
52
|
+
|
53
|
+
def load_features sources
|
54
|
+
io = StringIO.new
|
55
|
+
formatter = Gherkin::Formatter::JSONFormatter.new(io)
|
56
|
+
parser = Gherkin::Parser::Parser.new(formatter)
|
57
|
+
sources.each { |s| parser.parse(IO.read(s), s, 0) }
|
58
|
+
formatter.done
|
59
|
+
JSON.parse(io.string)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
58
63
|
end
|
data/lib/dsl.rb
CHANGED
@@ -1,111 +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
|
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
111
|
end
|
data/lib/feature_filters.rb
CHANGED
@@ -1,73 +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
|
-
|
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
73
|
end
|