cql 1.4.0 → 1.6.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 +5 -5
- data/lib/cql.rb +4 -169
- data/lib/cql/dsl.rb +39 -5
- data/lib/cql/feature_filters.rb +2 -0
- data/lib/cql/filters.rb +25 -1
- data/lib/cql/map_reduce.rb +3 -0
- data/lib/cql/model_dsl.rb +7 -1
- data/lib/cql/queriable.rb +6 -1
- data/lib/cql/query.rb +157 -0
- data/lib/cql/repository.rb +25 -0
- data/lib/cql/sso_filters.rb +4 -0
- data/lib/cql/version.rb +2 -1
- data/testing/cucumber/features/clauses/as_clause.feature +10 -9
- data/testing/cucumber/features/clauses/from_clause.feature +15 -20
- data/testing/cucumber/features/clauses/predefined_with_filters.feature +392 -0
- data/testing/cucumber/features/clauses/select_clause.feature +11 -14
- data/testing/cucumber/features/clauses/transform_clause.feature +10 -9
- data/testing/cucumber/features/clauses/with_clause.feature +10 -170
- data/testing/cucumber/features/dsl.feature +15 -34
- data/testing/cucumber/step_definitions/setup_steps.rb +1 -13
- data/testing/cucumber/step_definitions/verification_steps.rb +6 -7
- data/testing/cucumber/support/env.rb +9 -9
- data/testing/gemfiles/cuke_modeler0.gemfile +10 -7
- data/testing/gemfiles/cuke_modeler1.gemfile +6 -7
- data/testing/gemfiles/cuke_modeler2.gemfile +33 -0
- data/testing/gemfiles/cuke_modeler3.gemfile +10 -0
- data/testing/helper_methods.rb +13 -0
- data/testing/model_helper.rb +28 -0
- data/testing/rspec/spec/clauses/as_clause_spec.rb +1 -0
- data/testing/rspec/spec/clauses/from_clause_spec.rb +146 -0
- data/testing/rspec/spec/clauses/select_clause_spec.rb +184 -0
- data/testing/rspec/spec/clauses/transform_clause_spec.rb +35 -0
- data/testing/rspec/spec/clauses/with_clause_spec.rb +84 -0
- data/testing/rspec/spec/clauses/without_clause_spec.rb +171 -0
- data/testing/rspec/spec/cql_spec.rb +25 -0
- data/testing/rspec/spec/dsl_spec.rb +3 -575
- data/testing/rspec/spec/filter_example_spec.rb +1 -1
- data/testing/rspec/spec/filter_feature_dsl_spec.rb +13 -13
- data/testing/rspec/spec/filter_sso_spec.rb +2 -2
- data/testing/rspec/spec/line_filterable_specs.rb +1 -1
- data/testing/rspec/spec/map_reduce_spec.rb +1 -1
- data/testing/rspec/spec/model_query_spec.rb +1 -1
- data/testing/rspec/spec/multiple_queries_spec.rb +1 -1
- data/testing/rspec/spec/name_filterable_specs.rb +1 -1
- data/testing/rspec/spec/predefined_filters_spec.rb +284 -0
- data/testing/rspec/spec/repository_spec.rb +3 -3
- data/testing/rspec/spec/select_feature_dsl_spec.rb +8 -8
- data/testing/rspec/spec/select_scen_outline_dsl_spec.rb +14 -14
- data/testing/rspec/spec/select_scenario_dsl_spec.rb +9 -9
- data/testing/rspec/spec/spec_helper.rb +7 -17
- metadata +52 -23
- data/testing/cucumber/support/transforms.rb +0 -3
data/lib/cql/map_reduce.rb
CHANGED
@@ -6,10 +6,13 @@ require 'cql/dsl'
|
|
6
6
|
|
7
7
|
module CQL
|
8
8
|
|
9
|
+
# Not a part of the public API. Subject to change at any time.
|
9
10
|
class MapReduce
|
10
11
|
|
11
12
|
extend Dsl
|
12
13
|
|
14
|
+
|
15
|
+
# Recursively gathers all models that match the given targets and filters
|
13
16
|
def self.gather_objects(current_object, target_classes, filters)
|
14
17
|
gathered_objects = Array.new.tap { |gathered_objects| collect_all_in(target_classes, current_object, gathered_objects) }
|
15
18
|
|
data/lib/cql/model_dsl.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
|
-
# todo - add some
|
1
|
+
# todo - add some sort of error/warning if loading with the 0.x cuke_modeler?
|
2
2
|
|
3
3
|
module CukeModeler
|
4
|
+
|
5
|
+
# A monkey patch that allows models to be queried directly by having them use this gem's query module.
|
6
|
+
|
4
7
|
class Model
|
5
8
|
|
6
9
|
include CQL::Queriable
|
7
10
|
|
11
|
+
|
12
|
+
# Hanging on to the original method so that it can be invoked and thus ensure that all of the normal, un-patched behavior occurs
|
8
13
|
alias_method :original_initialize, :initialize
|
9
14
|
|
10
15
|
|
16
|
+
# Sets itself as the model's *query_root*. Otherwise, as per the un-patched method.
|
11
17
|
def initialize(source_text = nil)
|
12
18
|
original_initialize(source_text)
|
13
19
|
|
data/lib/cql/queriable.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
module CQL
|
2
|
+
|
3
|
+
# A mix-in module containing methods used by objects that want to be able to run queries against objects (often themselves).
|
4
|
+
|
2
5
|
module Queriable
|
3
6
|
|
4
|
-
|
7
|
+
# The object against which the query will be run.
|
8
|
+
attr_accessor :query_root # todo - deprecate this such that queries are always performed against *self*
|
5
9
|
|
6
10
|
|
11
|
+
# Performs a query against the current *query_root*
|
7
12
|
def query(&block)
|
8
13
|
raise(ArgumentError, 'Query cannot be run. No query root has been set.') unless @query_root
|
9
14
|
|
data/lib/cql/query.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
module CQL
|
2
|
+
|
3
|
+
# Not a part of the public API. Subject to change at any time.
|
4
|
+
class Query
|
5
|
+
|
6
|
+
include Dsl
|
7
|
+
|
8
|
+
# the root object that will be queried
|
9
|
+
attr_reader :data,
|
10
|
+
# what kinds of objects will be selected
|
11
|
+
:what
|
12
|
+
|
13
|
+
# Creates a new query object
|
14
|
+
def initialize(directory, &block)
|
15
|
+
# Set root object
|
16
|
+
@data = directory
|
17
|
+
|
18
|
+
# Populate configurables from DSL block
|
19
|
+
self.instance_eval(&block)
|
20
|
+
|
21
|
+
|
22
|
+
raise(ArgumentError, "A query must specify a 'select' clause") unless @what
|
23
|
+
raise(ArgumentError, "A query must specify a 'from' clause") unless @from
|
24
|
+
|
25
|
+
warn("Multiple selections made without using an 'as' clause") unless @name_transforms || (@what.count == @what.uniq.count)
|
26
|
+
|
27
|
+
# Gather relevant objects from root object and filters
|
28
|
+
@data = CQL::MapReduce.gather_objects(@data, @from, @filters)
|
29
|
+
|
30
|
+
# Extract properties from gathered objects
|
31
|
+
@data = format_output(@data)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
|
38
|
+
def format_output(data)
|
39
|
+
format_data(data)
|
40
|
+
end
|
41
|
+
|
42
|
+
def format_data data
|
43
|
+
space_data
|
44
|
+
|
45
|
+
Array.new.tap do |result_array|
|
46
|
+
data.each do |element|
|
47
|
+
result_array << Hash.new.tap do |result|
|
48
|
+
@what.each_with_index do |attribute, index|
|
49
|
+
key = determine_key(attribute, index)
|
50
|
+
value = determine_value(element, attribute, index)
|
51
|
+
|
52
|
+
result[key] = value
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def determine_key(attribute, index)
|
60
|
+
key = mapped_attribute(@name_transforms, attribute, index) if @name_transforms
|
61
|
+
|
62
|
+
key || attribute
|
63
|
+
end
|
64
|
+
|
65
|
+
def determine_value(element, attribute, index)
|
66
|
+
original_value = attribute.is_a?(Symbol) ? determine_special_value(element, attribute) : determine_normal_value(element, attribute)
|
67
|
+
|
68
|
+
if @value_transforms
|
69
|
+
value = mapped_attribute(@value_transforms, attribute, index)
|
70
|
+
value = value.call(original_value) if value.is_a?(Proc)
|
71
|
+
end
|
72
|
+
|
73
|
+
value || original_value
|
74
|
+
end
|
75
|
+
|
76
|
+
def determine_special_value(element, attribute)
|
77
|
+
# todo - Not sure what other special values to have but this could be expanded upon later.
|
78
|
+
case attribute
|
79
|
+
when :self, :model
|
80
|
+
val = element
|
81
|
+
else
|
82
|
+
raise(ArgumentError, ":#{attribute} is not a valid attribute for selection.")
|
83
|
+
end
|
84
|
+
|
85
|
+
val
|
86
|
+
end
|
87
|
+
|
88
|
+
def determine_normal_value(element, attribute)
|
89
|
+
if element.respond_to?(attribute)
|
90
|
+
element.send(attribute)
|
91
|
+
else
|
92
|
+
raise(ArgumentError, "'#{attribute}' is not a valid attribute for selection from a '#{element.class}'.")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def mapped_attribute(mappings, attribute, location)
|
97
|
+
case
|
98
|
+
when mappings.is_a?(Array)
|
99
|
+
value = mappings[location]
|
100
|
+
when mappings.is_a?(Hash)
|
101
|
+
if mappings[attribute]
|
102
|
+
value = mappings[attribute][location]
|
103
|
+
end
|
104
|
+
else
|
105
|
+
raise(ArgumentError, "Unknown mapping type '#{mappings.class}'")
|
106
|
+
end
|
107
|
+
|
108
|
+
value
|
109
|
+
end
|
110
|
+
|
111
|
+
def space_data
|
112
|
+
space_renamings
|
113
|
+
space_transforms
|
114
|
+
end
|
115
|
+
|
116
|
+
def space_renamings
|
117
|
+
if @name_transforms.is_a?(Hash)
|
118
|
+
new_names = {}
|
119
|
+
|
120
|
+
@name_transforms.each_pair do |key, value|
|
121
|
+
new_names[key] = []
|
122
|
+
|
123
|
+
@what.each do |attribute|
|
124
|
+
if attribute == key
|
125
|
+
new_names[key] << value.shift
|
126
|
+
else
|
127
|
+
new_names[key] << nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
@name_transforms = new_names
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def space_transforms
|
137
|
+
if @value_transforms.is_a?(Hash)
|
138
|
+
new_values = {}
|
139
|
+
|
140
|
+
@value_transforms.each_pair do |key, value|
|
141
|
+
new_values[key] = []
|
142
|
+
|
143
|
+
@what.each do |attribute|
|
144
|
+
if attribute == key
|
145
|
+
new_values[key] << value.shift
|
146
|
+
else
|
147
|
+
new_values[key] << nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
@value_transforms = new_values
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CQL
|
2
|
+
|
3
|
+
# A repository is a group of models. See the corresponding Cucumber documentation for details.
|
4
|
+
|
5
|
+
class Repository
|
6
|
+
|
7
|
+
include Queriable
|
8
|
+
|
9
|
+
|
10
|
+
# Creates a new repository object based on the passed directory path or model
|
11
|
+
def initialize(repository_root)
|
12
|
+
case
|
13
|
+
when repository_root.is_a?(String)
|
14
|
+
root = CukeModeler::Directory.new(repository_root)
|
15
|
+
when repository_root.class.to_s =~ /CukeModeler/
|
16
|
+
root = repository_root
|
17
|
+
else
|
18
|
+
raise(ArgumentError, "Don't know how to make a repository from a #{repository_root.class}")
|
19
|
+
end
|
20
|
+
|
21
|
+
@query_root = root
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/cql/sso_filters.rb
CHANGED
@@ -3,16 +3,20 @@ require 'cql/filters'
|
|
3
3
|
|
4
4
|
module CQL
|
5
5
|
|
6
|
+
# Not a part of the public API. Subject to change at any time.
|
6
7
|
class SsoLineCountFilter < TypeCountFilter
|
7
8
|
|
9
|
+
# Counts the numbers of steps on a test
|
8
10
|
def type_count(test)
|
9
11
|
test.steps.size
|
10
12
|
end
|
11
13
|
|
12
14
|
end
|
13
15
|
|
16
|
+
# Not a part of the public API. Subject to change at any time.
|
14
17
|
class LineFilter < ContentMatchFilter
|
15
18
|
|
19
|
+
# Filters the input models so that only the desired ones are returned
|
16
20
|
def execute(input, negate)
|
17
21
|
method_for_filtering = negate ? :reject : :select
|
18
22
|
method_for_text = Gem.loaded_specs['cuke_modeler'].version.version[/^0/] ? :base : :text
|
data/lib/cql/version.rb
CHANGED
@@ -2,12 +2,14 @@ Feature: 'as' clause'
|
|
2
2
|
|
3
3
|
The *as* clause allows you to change the keys under which the model attributes specified by the *select* clause will be gathered. Key renaming can be done as a list of new names that are applied in order or as a mapping of specific keys to their new names.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
Sample usage:
|
6
|
+
````
|
7
|
+
cql_repo.query do
|
8
|
+
select name
|
9
|
+
as title
|
10
|
+
from features
|
11
|
+
end
|
12
|
+
````
|
11
13
|
|
12
14
|
This will return a list of all of the feature names but under the key of 'title' instead of 'name'.
|
13
15
|
|
@@ -15,8 +17,8 @@ Feature: 'as' clause'
|
|
15
17
|
|
16
18
|
|
17
19
|
Background: A sample Cucumber suite
|
18
|
-
Given a
|
19
|
-
And
|
20
|
+
Given a repository to query
|
21
|
+
And the following feature has been modeled in the repository:
|
20
22
|
"""
|
21
23
|
Feature: A test feature
|
22
24
|
|
@@ -36,7 +38,6 @@ Feature: 'as' clause'
|
|
36
38
|
| param |
|
37
39
|
| value |
|
38
40
|
"""
|
39
|
-
And a repository is made from "test_directory"
|
40
41
|
|
41
42
|
|
42
43
|
Scenario: Using 'as' to change the name under which values are returned
|
@@ -4,22 +4,26 @@ Feature: 'from' clause
|
|
4
4
|
|
5
5
|
The following are some example values:
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
````
|
8
|
+
CukeModeler::Outline # exact class
|
9
|
+
outline # singular
|
10
|
+
outlines # pluralized
|
11
|
+
````
|
12
|
+
|
13
|
+
Sample usage:
|
14
|
+
````
|
15
|
+
cql_repo.query do
|
16
|
+
select name
|
17
|
+
from scenarios
|
18
|
+
end
|
19
|
+
````
|
16
20
|
|
17
21
|
This clause can be repeated multiple times. The arguments for successive clauses are simply added to the previous arguments.
|
18
22
|
|
19
23
|
|
20
24
|
Background: A sample Cucumber suite
|
21
|
-
Given a
|
22
|
-
And
|
25
|
+
Given a repository to query
|
26
|
+
And the following feature has been modeled in the repository:
|
23
27
|
"""
|
24
28
|
Feature: A test feature
|
25
29
|
|
@@ -39,7 +43,6 @@ Feature: 'from' clause
|
|
39
43
|
| param |
|
40
44
|
| value |
|
41
45
|
"""
|
42
|
-
And a repository is made from "test_directory"
|
43
46
|
|
44
47
|
|
45
48
|
Scenario: Using 'from' to specify what kind of objects from which to return attributes
|
@@ -116,11 +119,3 @@ Feature: 'from' clause
|
|
116
119
|
from :all
|
117
120
|
"""
|
118
121
|
Then all models are queried from
|
119
|
-
|
120
|
-
|
121
|
-
# Commented out so that they aren't picked up by Relish
|
122
|
-
# @wip
|
123
|
-
# Scenario: Can 'from' from all type of model
|
124
|
-
#
|
125
|
-
# @wip
|
126
|
-
# Scenario: From-ing from a collection
|
@@ -0,0 +1,392 @@
|
|
1
|
+
# todo - Rewrite the scenarios such that they use their own test specific feature files instead of setting up a large suite in the background
|
2
|
+
Feature: 'with' clause
|
3
|
+
|
4
|
+
There are several predefined filters that can be used with the *with* clause. Like regular 'block style' conditions, they can be negated using *without*, used in a targeted fashion, etc.
|
5
|
+
|
6
|
+
Sample usage:
|
7
|
+
````
|
8
|
+
cql_repo.query do
|
9
|
+
select name, tags, description_text
|
10
|
+
from features
|
11
|
+
with tc lt 3
|
12
|
+
end
|
13
|
+
````
|
14
|
+
|
15
|
+
The following filters are supported for models that have tags:
|
16
|
+
|
17
|
+
* tags - Filters out models that do not have the exact set of tags provided.
|
18
|
+
* tc - (tag count) Filters out models based on the number of tags that they have.
|
19
|
+
|
20
|
+
The following filters are supported for models that have names:
|
21
|
+
|
22
|
+
* name - Filters out models whose name does not match the name provided. Can be a string or regular expression.
|
23
|
+
|
24
|
+
The following filters are supported for models that have steps:
|
25
|
+
|
26
|
+
* line - Filters out models whose steps do not include the provided step (keywords and blocks are ignored). Can be a string or regular expression.
|
27
|
+
* lc - (line count) Filters out models based on the number of steps that they have.
|
28
|
+
|
29
|
+
The following filters are supported for feature models:
|
30
|
+
|
31
|
+
* sc - (scenario count) Filters out models based on the number of scenarios that they have.
|
32
|
+
* soc - (scenario outline count) Filters out models based on the number of outlines that they have.
|
33
|
+
* ssoc - (scenario and scenario outline count) Filters out models based on the total number of scenarios and outlines that they have.
|
34
|
+
|
35
|
+
For count based filters, the following operators are available:
|
36
|
+
|
37
|
+
* lt (Less than)
|
38
|
+
* lte (Less than or equals)
|
39
|
+
* gt (Greater than)
|
40
|
+
* gte (Greater than or equals)
|
41
|
+
* eq (Equals)
|
42
|
+
|
43
|
+
|
44
|
+
Background: A sample Cucumber suite
|
45
|
+
Given a repository to query
|
46
|
+
And the following feature has been modeled in the repository:
|
47
|
+
"""
|
48
|
+
Feature: A test feature
|
49
|
+
|
50
|
+
@tag_1 @tag_2
|
51
|
+
Scenario: Test 1
|
52
|
+
* some steps
|
53
|
+
|
54
|
+
@special_tag @tag_2
|
55
|
+
Scenario: Test 2
|
56
|
+
* some other steps
|
57
|
+
* some other steps
|
58
|
+
* some other steps
|
59
|
+
|
60
|
+
@a @b @c
|
61
|
+
Scenario Outline: Test 3
|
62
|
+
* some steps
|
63
|
+
* some more steps
|
64
|
+
* some more steps
|
65
|
+
* some more steps
|
66
|
+
Examples: First examples
|
67
|
+
| param |
|
68
|
+
| value |
|
69
|
+
Examples: Second examples
|
70
|
+
| param |
|
71
|
+
| value |
|
72
|
+
|
73
|
+
Scenario: Test 4
|
74
|
+
"""
|
75
|
+
And the following feature has been modeled in the repository:
|
76
|
+
"""
|
77
|
+
Feature: A feature with lots of scenarios
|
78
|
+
|
79
|
+
Scenario: 1
|
80
|
+
* different steps
|
81
|
+
* different steps
|
82
|
+
|
83
|
+
Scenario: 2
|
84
|
+
* different steps
|
85
|
+
* different steps
|
86
|
+
|
87
|
+
Scenario: 3
|
88
|
+
* different steps
|
89
|
+
* different steps
|
90
|
+
"""
|
91
|
+
And the following feature has been modeled in the repository:
|
92
|
+
"""
|
93
|
+
Feature: A feature with lots of outlines
|
94
|
+
|
95
|
+
Scenario Outline: 1
|
96
|
+
* different steps
|
97
|
+
* different steps
|
98
|
+
Examples:
|
99
|
+
| param |
|
100
|
+
| value |
|
101
|
+
|
102
|
+
Scenario Outline: 2
|
103
|
+
* different steps
|
104
|
+
* different steps
|
105
|
+
Examples:
|
106
|
+
| param |
|
107
|
+
| value |
|
108
|
+
|
109
|
+
Scenario Outline: 3
|
110
|
+
* different steps
|
111
|
+
* different steps
|
112
|
+
Examples:
|
113
|
+
| param |
|
114
|
+
| value |
|
115
|
+
"""
|
116
|
+
And the following feature has been modeled in the repository:
|
117
|
+
"""
|
118
|
+
Feature: A feature with a mix of tests
|
119
|
+
|
120
|
+
Scenario: 4
|
121
|
+
* different steps
|
122
|
+
* different steps
|
123
|
+
|
124
|
+
Scenario Outline: 4
|
125
|
+
* different steps
|
126
|
+
* different steps
|
127
|
+
Examples:
|
128
|
+
| param |
|
129
|
+
| value |
|
130
|
+
"""
|
131
|
+
|
132
|
+
|
133
|
+
Scenario: Filtering by tags
|
134
|
+
When the following query is executed:
|
135
|
+
"""
|
136
|
+
select name
|
137
|
+
from scenarios
|
138
|
+
with tags '@tag_1', '@tag_2'
|
139
|
+
"""
|
140
|
+
Then the following values are returned:
|
141
|
+
| name |
|
142
|
+
| Test 1 |
|
143
|
+
|
144
|
+
Scenario: Filtering by tag count
|
145
|
+
When the following query is executed:
|
146
|
+
"""
|
147
|
+
select name
|
148
|
+
from scenarios, outlines
|
149
|
+
with tc gt 2
|
150
|
+
"""
|
151
|
+
Then the following values are returned:
|
152
|
+
| name |
|
153
|
+
| Test 3 |
|
154
|
+
|
155
|
+
Scenario: Filtering by name (exact match)
|
156
|
+
When the following query is executed:
|
157
|
+
"""
|
158
|
+
select name
|
159
|
+
from scenarios, outlines
|
160
|
+
with name 'Test 3'
|
161
|
+
"""
|
162
|
+
Then the following values are returned:
|
163
|
+
| name |
|
164
|
+
| Test 3 |
|
165
|
+
|
166
|
+
Scenario: Filtering by name (regular expression)
|
167
|
+
When the following query is executed:
|
168
|
+
"""
|
169
|
+
select name
|
170
|
+
from scenarios, outlines
|
171
|
+
with name /Test [12]/
|
172
|
+
"""
|
173
|
+
Then the following values are returned:
|
174
|
+
| name |
|
175
|
+
| Test 1 |
|
176
|
+
| Test 2 |
|
177
|
+
|
178
|
+
Scenario: Filtering by line (exact match)
|
179
|
+
When the following query is executed:
|
180
|
+
"""
|
181
|
+
select name
|
182
|
+
from scenarios, outlines
|
183
|
+
with line 'some steps'
|
184
|
+
"""
|
185
|
+
Then the following values are returned:
|
186
|
+
| name |
|
187
|
+
| Test 1 |
|
188
|
+
| Test 3 |
|
189
|
+
|
190
|
+
Scenario: Filtering by line (regular expression)
|
191
|
+
When the following query is executed:
|
192
|
+
"""
|
193
|
+
select name
|
194
|
+
from scenarios, outlines
|
195
|
+
with line /other/
|
196
|
+
"""
|
197
|
+
Then the following values are returned:
|
198
|
+
| name |
|
199
|
+
| Test 2 |
|
200
|
+
|
201
|
+
Scenario: Filtering by line count
|
202
|
+
When the following query is executed:
|
203
|
+
"""
|
204
|
+
select name
|
205
|
+
from scenarios, outlines
|
206
|
+
with lc gt 3
|
207
|
+
"""
|
208
|
+
Then the following values are returned:
|
209
|
+
| name |
|
210
|
+
| Test 3 |
|
211
|
+
|
212
|
+
Scenario: Filtering by scenario count
|
213
|
+
When the following query is executed:
|
214
|
+
"""
|
215
|
+
select name
|
216
|
+
from features
|
217
|
+
with sc gt 2
|
218
|
+
"""
|
219
|
+
Then the following values are returned:
|
220
|
+
| name |
|
221
|
+
| A test feature |
|
222
|
+
| A feature with lots of scenarios |
|
223
|
+
|
224
|
+
Scenario: Filtering by outline count
|
225
|
+
When the following query is executed:
|
226
|
+
"""
|
227
|
+
select name
|
228
|
+
from features
|
229
|
+
with soc gt 2
|
230
|
+
"""
|
231
|
+
Then the following values are returned:
|
232
|
+
| name |
|
233
|
+
| A feature with lots of outlines |
|
234
|
+
|
235
|
+
Scenario: Filtering by combined test count
|
236
|
+
When the following query is executed:
|
237
|
+
"""
|
238
|
+
select name
|
239
|
+
from features
|
240
|
+
with ssoc lt 3
|
241
|
+
"""
|
242
|
+
Then the following values are returned:
|
243
|
+
| name |
|
244
|
+
| A feature with a mix of tests |
|
245
|
+
|
246
|
+
Scenario: Using the 'lt' count filter
|
247
|
+
When the following query is executed:
|
248
|
+
"""
|
249
|
+
select name
|
250
|
+
from features
|
251
|
+
with ssoc lt 3
|
252
|
+
"""
|
253
|
+
Then the following values are returned:
|
254
|
+
| name |
|
255
|
+
| A feature with a mix of tests |
|
256
|
+
|
257
|
+
Scenario: Using the 'lte' count filter
|
258
|
+
When the following query is executed:
|
259
|
+
"""
|
260
|
+
select name
|
261
|
+
from scenarios, outlines
|
262
|
+
with lc lte 1
|
263
|
+
"""
|
264
|
+
Then the following values are returned:
|
265
|
+
| name |
|
266
|
+
| Test 1 |
|
267
|
+
| Test 4 |
|
268
|
+
|
269
|
+
Scenario: Using the 'gt' count filter
|
270
|
+
When the following query is executed:
|
271
|
+
"""
|
272
|
+
select name
|
273
|
+
from scenarios, outlines
|
274
|
+
with lc gt 3
|
275
|
+
"""
|
276
|
+
Then the following values are returned:
|
277
|
+
| name |
|
278
|
+
| Test 3 |
|
279
|
+
|
280
|
+
Scenario: Using the 'gte' count filter
|
281
|
+
When the following query is executed:
|
282
|
+
"""
|
283
|
+
select name
|
284
|
+
from scenarios, outlines
|
285
|
+
with lc gte 3
|
286
|
+
"""
|
287
|
+
Then the following values are returned:
|
288
|
+
| name |
|
289
|
+
| Test 2 |
|
290
|
+
| Test 3 |
|
291
|
+
|
292
|
+
Scenario: Using the 'eq' count filter
|
293
|
+
When the following query is executed:
|
294
|
+
"""
|
295
|
+
select name
|
296
|
+
from scenarios, outlines
|
297
|
+
with tc eq 3
|
298
|
+
"""
|
299
|
+
Then the following values are returned:
|
300
|
+
| name |
|
301
|
+
| Test 3 |
|
302
|
+
|
303
|
+
|
304
|
+
Scenario: Using multiple filters
|
305
|
+
When the following query is executed:
|
306
|
+
"""
|
307
|
+
select name
|
308
|
+
from scenarios
|
309
|
+
with tc eq 2
|
310
|
+
with lc gt 1
|
311
|
+
"""
|
312
|
+
Then the following values are returned:
|
313
|
+
| name |
|
314
|
+
| Test 2 |
|
315
|
+
|
316
|
+
Scenario: Using the 'with' clause multiple times
|
317
|
+
|
318
|
+
Behavior is the same as combining regular, block style filters but the syntax has to become more explicit.
|
319
|
+
|
320
|
+
When the following query is executed:
|
321
|
+
"""
|
322
|
+
select name
|
323
|
+
from scenarios
|
324
|
+
with tc(eq(2)),
|
325
|
+
lc(gt(1))
|
326
|
+
"""
|
327
|
+
Then the result is the same as the result of the following query:
|
328
|
+
"""
|
329
|
+
select name
|
330
|
+
from scenarios
|
331
|
+
with tc eq 2
|
332
|
+
with lc gt 1
|
333
|
+
"""
|
334
|
+
|
335
|
+
Scenario: Selectively filtering models
|
336
|
+
When the following query is executed:
|
337
|
+
"""
|
338
|
+
select name
|
339
|
+
from scenarios, features
|
340
|
+
with scenarios => lc(eq(1))
|
341
|
+
"""
|
342
|
+
Then the following values are returned:
|
343
|
+
| name |
|
344
|
+
| Test 1 |
|
345
|
+
| A test feature |
|
346
|
+
| A feature with lots of scenarios |
|
347
|
+
| A feature with lots of outlines |
|
348
|
+
| A feature with a mix of tests |
|
349
|
+
|
350
|
+
|
351
|
+
Scenario: Mixing targeted and blanket filters
|
352
|
+
When the following query is executed:
|
353
|
+
"""
|
354
|
+
select name
|
355
|
+
from scenarios, features
|
356
|
+
with name /test/i
|
357
|
+
with scenarios => tc(eq(0))
|
358
|
+
"""
|
359
|
+
Then the following values are returned:
|
360
|
+
| name |
|
361
|
+
| Test 4 |
|
362
|
+
| A test feature |
|
363
|
+
| A feature with a mix of tests |
|
364
|
+
|
365
|
+
Scenario: Using 'without' for negation
|
366
|
+
When the following query is executed:
|
367
|
+
"""
|
368
|
+
select name
|
369
|
+
from features
|
370
|
+
without ssoc lt 3
|
371
|
+
"""
|
372
|
+
Then the result is the same as the result of the following query:
|
373
|
+
"""
|
374
|
+
select name
|
375
|
+
from features
|
376
|
+
with ssoc gt 2
|
377
|
+
"""
|
378
|
+
|
379
|
+
Scenario: Mixing predefined filters and regular filters
|
380
|
+
When the following query is executed:
|
381
|
+
"""
|
382
|
+
select name
|
383
|
+
from scenarios, features
|
384
|
+
with { |element| element.name =~ /test/i }
|
385
|
+
with scenarios => tc(eq(0))
|
386
|
+
"""
|
387
|
+
Then the following values are returned:
|
388
|
+
| name |
|
389
|
+
| Test 4 |
|
390
|
+
| A test feature |
|
391
|
+
| A feature with a mix of tests |
|
392
|
+
|