cql 1.4.1 → 1.7.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/dsl.rb +11 -1
- data/lib/cql/filters.rb +14 -1
- data/lib/cql/query.rb +5 -2
- data/lib/cql/repository.rb +1 -0
- data/lib/cql/version.rb +1 -1
- data/testing/cucumber/features/clauses/from_clause.feature +0 -8
- data/testing/cucumber/features/clauses/predefined_with_filters.feature +392 -0
- data/testing/cucumber/features/clauses/select_clause.feature +1 -5
- data/testing/cucumber/features/clauses/with_clause.feature +2 -164
- data/testing/cucumber/features/dsl.feature +0 -22
- data/testing/cucumber/step_definitions/verification_steps.rb +5 -6
- data/testing/gemfiles/cuke_modeler0.gemfile +9 -7
- data/testing/gemfiles/cuke_modeler1.gemfile +5 -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 +31 -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 +67 -40
- data/testing/cucumber/support/transforms.rb +0 -3
@@ -92,7 +92,7 @@ Feature: 'select' clause
|
|
92
92
|
from scenarios
|
93
93
|
"""
|
94
94
|
|
95
|
-
Scenario:
|
95
|
+
Scenario: Using the 'select' clause multiple times
|
96
96
|
When the following query is executed:
|
97
97
|
"""
|
98
98
|
select name
|
@@ -116,7 +116,3 @@ Feature: 'select' clause
|
|
116
116
|
select :self
|
117
117
|
from scenarios
|
118
118
|
"""
|
119
|
-
|
120
|
-
# Commented out so that they aren't picked up by Relish
|
121
|
-
# @wip
|
122
|
-
# Scenario: Can select from all types of model
|
@@ -1,7 +1,7 @@
|
|
1
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
2
|
Feature: 'with' clause
|
3
3
|
|
4
|
-
The *with* clause specifies filter conditions that will reduce the number of things targeted by the *from* clause. The *with* clause can take one or more blocks that will filter out any object for which the block does not evaluate to true (using 'without' instead of 'with' will have the opposite effect). Alternatively, mappings of specific *from* targets to their respective filtering blocks can be provided. The *with* clause can also take predefined filters (
|
4
|
+
The *with* clause specifies filter conditions that will reduce the number of things targeted by the *from* clause. The *with* clause can take one or more blocks that will filter out any object for which the block does not evaluate to true (using 'without' instead of 'with' will have the opposite effect). Alternatively, mappings of specific *from* targets to their respective filtering blocks can be provided. The *with* clause can also take predefined filters (see corresponding documentation).
|
5
5
|
|
6
6
|
Sample usage:
|
7
7
|
````
|
@@ -9,41 +9,12 @@ Feature: 'with' clause
|
|
9
9
|
select name, tags, description_text
|
10
10
|
from features
|
11
11
|
with { |feature| feature.name =~ /foo/ }
|
12
|
-
with tc lt 3
|
13
12
|
end
|
14
13
|
````
|
15
14
|
|
16
15
|
This clause can be repeated multiple times. The arguments for successive clauses are simply added to the previous arguments.
|
17
16
|
|
18
17
|
|
19
|
-
The following filters are supported for models that have tags:
|
20
|
-
|
21
|
-
* tags - Filters out models that do not have the exact set of tags provided.
|
22
|
-
* tc - (tag count) Filters out models based on the number of tags that they have.
|
23
|
-
|
24
|
-
The following filters are supported for models that have names:
|
25
|
-
|
26
|
-
* name - Filters out models whose name does not match the name provided. Can be a string or regular expression.
|
27
|
-
|
28
|
-
The following filters are supported for models that have steps:
|
29
|
-
|
30
|
-
* line - Filters out models whose steps do not include the provided step (keywords and blocks are ignored). Can be a string or regular expression.
|
31
|
-
* lc - (line count) Filters out models based on the number of steps that they have.
|
32
|
-
|
33
|
-
The following filters are supported for feature models:
|
34
|
-
|
35
|
-
* sc - (scenario count) Filters out models based on the number of scenarios that they have.
|
36
|
-
* soc - (scenario outline count) Filters out models based on the number of outlines that they have.
|
37
|
-
* ssoc - (scenario and scenario outline count) Filters out models based on the total number of scenarios and outlines that they have.
|
38
|
-
|
39
|
-
For count based filters, the following operators are available:
|
40
|
-
|
41
|
-
* lt (Less than)
|
42
|
-
* lte (Less than or equals)
|
43
|
-
* gt (Greater than)
|
44
|
-
* gte (Greater than or equals)
|
45
|
-
|
46
|
-
|
47
18
|
Background: A sample Cucumber suite
|
48
19
|
Given a repository to query
|
49
20
|
And the following feature has been modeled in the repository:
|
@@ -161,7 +132,7 @@ Feature: 'with' clause
|
|
161
132
|
"""
|
162
133
|
select name
|
163
134
|
from features, scenarios
|
164
|
-
with scenarios =>
|
135
|
+
with scenarios => lambda { |element| element.name == 'Test 1' }
|
165
136
|
"""
|
166
137
|
Then the following values are returned:
|
167
138
|
| name |
|
@@ -216,127 +187,6 @@ Feature: 'with' clause
|
|
216
187
|
| A feature with lots of scenarios |
|
217
188
|
| A feature with lots of outlines |
|
218
189
|
|
219
|
-
# todo - break out the predefined filters into another feature file?
|
220
|
-
Scenario: Filtering by tags
|
221
|
-
When the following query is executed:
|
222
|
-
"""
|
223
|
-
select name
|
224
|
-
from scenarios
|
225
|
-
with tags '@tag_1', '@tag_2'
|
226
|
-
"""
|
227
|
-
Then the following values are returned:
|
228
|
-
| name |
|
229
|
-
| Test 1 |
|
230
|
-
|
231
|
-
Scenario: Filtering by tag count
|
232
|
-
When the following query is executed:
|
233
|
-
"""
|
234
|
-
select name
|
235
|
-
from scenarios, outlines
|
236
|
-
with tc gt 2
|
237
|
-
"""
|
238
|
-
Then the following values are returned:
|
239
|
-
| name |
|
240
|
-
| Test 3 |
|
241
|
-
|
242
|
-
Scenario: Filtering by name
|
243
|
-
When the following query is executed:
|
244
|
-
"""
|
245
|
-
select name
|
246
|
-
from scenarios, outlines
|
247
|
-
with name 'Test 3'
|
248
|
-
"""
|
249
|
-
Then the following values are returned:
|
250
|
-
| name |
|
251
|
-
| Test 3 |
|
252
|
-
When the following query is executed:
|
253
|
-
"""
|
254
|
-
select name
|
255
|
-
from scenarios, outlines
|
256
|
-
with name /Test [12]/
|
257
|
-
"""
|
258
|
-
Then the following values are returned:
|
259
|
-
| name |
|
260
|
-
| Test 1 |
|
261
|
-
| Test 2 |
|
262
|
-
|
263
|
-
Scenario: Filtering by line
|
264
|
-
When the following query is executed:
|
265
|
-
"""
|
266
|
-
select name
|
267
|
-
from scenarios, outlines
|
268
|
-
with line 'some steps'
|
269
|
-
"""
|
270
|
-
Then the following values are returned:
|
271
|
-
| name |
|
272
|
-
| Test 1 |
|
273
|
-
| Test 3 |
|
274
|
-
When the following query is executed:
|
275
|
-
"""
|
276
|
-
select name
|
277
|
-
from scenarios, outlines
|
278
|
-
with line /other/
|
279
|
-
"""
|
280
|
-
Then the following values are returned:
|
281
|
-
| name |
|
282
|
-
| Test 2 |
|
283
|
-
|
284
|
-
Scenario: Filtering by line count
|
285
|
-
When the following query is executed:
|
286
|
-
"""
|
287
|
-
select name
|
288
|
-
from scenarios, outlines
|
289
|
-
with lc gt 1
|
290
|
-
"""
|
291
|
-
Then the following values are returned:
|
292
|
-
| name |
|
293
|
-
| Test 3 |
|
294
|
-
|
295
|
-
Scenario: Filtering by scenario count
|
296
|
-
When the following query is executed:
|
297
|
-
"""
|
298
|
-
select name
|
299
|
-
from features
|
300
|
-
with sc gt 2
|
301
|
-
"""
|
302
|
-
Then the following values are returned:
|
303
|
-
| name |
|
304
|
-
| A feature with lots of scenarios |
|
305
|
-
|
306
|
-
Scenario: Filtering by outline count
|
307
|
-
When the following query is executed:
|
308
|
-
"""
|
309
|
-
select name
|
310
|
-
from features
|
311
|
-
with soc gt 2
|
312
|
-
"""
|
313
|
-
Then the following values are returned:
|
314
|
-
| name |
|
315
|
-
| A feature with lots of outlines |
|
316
|
-
|
317
|
-
Scenario: Filtering by combined test count
|
318
|
-
When the following query is executed:
|
319
|
-
"""
|
320
|
-
select name
|
321
|
-
from features
|
322
|
-
with ssoc lt 3
|
323
|
-
"""
|
324
|
-
Then the following values are returned:
|
325
|
-
| name |
|
326
|
-
| A feature with a mix of tests |
|
327
|
-
|
328
|
-
@wip
|
329
|
-
Scenario: Using the 'lt' count filter
|
330
|
-
|
331
|
-
@wip
|
332
|
-
Scenario: Using the 'lte' count filter
|
333
|
-
|
334
|
-
@wip
|
335
|
-
Scenario: Using the 'gt' count filter
|
336
|
-
|
337
|
-
@wip
|
338
|
-
Scenario: Using the 'gte' count filter
|
339
|
-
|
340
190
|
Scenario: Using 'without' for negation
|
341
191
|
When the following query is executed:
|
342
192
|
"""
|
@@ -350,15 +200,3 @@ Feature: 'with' clause
|
|
350
200
|
from scenarios
|
351
201
|
with { |scenario| !(scenario.source_line == 8) }
|
352
202
|
"""
|
353
|
-
When the following query is executed:
|
354
|
-
"""
|
355
|
-
select name
|
356
|
-
from features
|
357
|
-
without ssoc lt 3
|
358
|
-
"""
|
359
|
-
Then the result is the same as the result of the following query:
|
360
|
-
"""
|
361
|
-
select name
|
362
|
-
from features
|
363
|
-
with ssoc gt 2
|
364
|
-
"""
|
@@ -56,25 +56,3 @@ Feature: DSL
|
|
56
56
|
select 'name'
|
57
57
|
from 'scenarios'
|
58
58
|
"""
|
59
|
-
|
60
|
-
|
61
|
-
# Commented out so that they aren't picked up by Relish
|
62
|
-
#
|
63
|
-
# @wip
|
64
|
-
# Scenario: Use 'order_by' to sort the results
|
65
|
-
#
|
66
|
-
# # 'and' is a keyword. Some other kind of repeater word would be needed
|
67
|
-
# @wip
|
68
|
-
# Scenario: 'And' can be used instead of repeating the previous keyword
|
69
|
-
# When the following query is executed:
|
70
|
-
# """
|
71
|
-
# select 'name'
|
72
|
-
# and 'source_line'
|
73
|
-
# from CukeModeler::Scenario
|
74
|
-
# and CukeModeler::Outline
|
75
|
-
# """
|
76
|
-
# Then the following values are returned:
|
77
|
-
# | name | source_line |
|
78
|
-
# | Test 1 | 3 |
|
79
|
-
# | Test 2 | 6 |
|
80
|
-
# | Test 3 | 9 |
|
@@ -2,16 +2,15 @@ Then(/^the following values are returned:$/) do |values|
|
|
2
2
|
expected_keys = values.raw.first
|
3
3
|
expected_results = values.hashes
|
4
4
|
|
5
|
+
# Protecting against false positives
|
6
|
+
# Key order doesn't matter and Ruby 1.8.7 does not retain hash key ordering, so sorting them for consistency
|
7
|
+
raise('Invalid result set. Attribute names cannot be repeated.') unless expected_keys.sort == expected_results.first.keys.sort
|
8
|
+
|
5
9
|
expected_results.each do |result|
|
6
10
|
result.each_pair { |key, value| result[key] = value.to_i if value =~ /^\d+$/ }
|
7
11
|
end
|
8
12
|
|
9
|
-
|
10
|
-
@query_results.each_with_index do |result, index|
|
11
|
-
# Key order doesn't matter and Ruby 1.8.7 does not retain hash key ordering, so sorting them for consistency
|
12
|
-
expect(result.keys.sort).to eq(expected_keys.sort)
|
13
|
-
expect(result).to eq(expected_results[index])
|
14
|
-
end
|
13
|
+
expect(@query_results).to match_array(expected_results)
|
15
14
|
end
|
16
15
|
|
17
16
|
# Then(/^all of them can be queried for additional information$/) do
|
@@ -7,13 +7,12 @@ gemspec :path => "../../"
|
|
7
7
|
if RUBY_VERSION =~ /^1\.8/
|
8
8
|
gem 'cucumber', '< 1.3.0'
|
9
9
|
gem 'gherkin', '< 2.12.0'
|
10
|
-
gem '
|
11
|
-
gem 'rest-client', '< 1.7.0' # (For the relish gem) Ruby 1.8.x dropped on/after this version
|
10
|
+
gem 'rainbow', '< 2.0' # Ruby 1.8.x support dropped after this version
|
12
11
|
gem 'rake', '< 11.0' # Rake dropped 1.8.x support after this version
|
13
12
|
elsif RUBY_VERSION =~ /^1\./
|
14
13
|
gem 'cucumber', '< 2.0.0'
|
15
14
|
gem 'mime-types', '< 3.0.0' # Requires Ruby 2.x on/after this version
|
16
|
-
gem '
|
15
|
+
gem 'rake', '< 12.3.0' # Requires Ruby 2.x on/after this version
|
17
16
|
end
|
18
17
|
|
19
18
|
if RUBY_VERSION =~ /^1\./
|
@@ -21,14 +20,17 @@ if RUBY_VERSION =~ /^1\./
|
|
21
20
|
gem 'json', '< 2.0' # The 'json' gem drops pre-Ruby 2.x support on/after this version
|
22
21
|
gem 'term-ansicolor', '< 1.4' # The 'term-ansicolor' gem requires Ruby 2.x on/after this version
|
23
22
|
gem 'unf_ext', '< 0.0.7.3' # Requires Ruby 2.x on/after this version
|
24
|
-
|
25
|
-
if RbConfig::CONFIG['host_os'].downcase =~ /mswin|msys|mingw32/
|
26
|
-
gem 'ffi', '< 1.9.15' # The 'ffi' gem, for Windows, requires Ruby 2.x on/after this version
|
27
|
-
end
|
28
23
|
end
|
29
24
|
|
30
25
|
if RUBY_VERSION =~ /^2\.[23456789]/
|
31
26
|
gem 'test-unit'
|
27
|
+
# Cucumber 4.x uses the `cucumber-gherkin` gem, which is incompatible with
|
28
|
+
# the `gherkin` gem, upon which the `cuke_modeler` gem depends
|
29
|
+
gem 'cucumber', '< 4.0'
|
30
|
+
|
31
|
+
# The oldest versions of the `cuke_modeler` gem did not properly limit their dependencies
|
32
|
+
# and CukeModeler 0.x can not handle a higher Gherkin 5.x+
|
33
|
+
gem 'gherkin', '< 5.0'
|
32
34
|
end
|
33
35
|
|
34
36
|
|
@@ -7,13 +7,12 @@ gemspec :path => "../../"
|
|
7
7
|
if RUBY_VERSION =~ /^1\.8/
|
8
8
|
gem 'cucumber', '< 1.3.0'
|
9
9
|
gem 'gherkin', '< 2.12.0'
|
10
|
-
gem '
|
11
|
-
gem 'rest-client', '< 1.7.0' # (For the relish gem) Ruby 1.8.x dropped on/after this version
|
10
|
+
gem 'rainbow', '< 2.0' # Ruby 1.8.x support dropped after this version
|
12
11
|
gem 'rake', '< 11.0' # Rake dropped 1.8.x support after this version
|
13
12
|
elsif RUBY_VERSION =~ /^1\./
|
14
13
|
gem 'cucumber', '< 2.0.0'
|
15
14
|
gem 'mime-types', '< 3.0.0' # Requires Ruby 2.x on/after this version
|
16
|
-
gem '
|
15
|
+
gem 'rake', '< 12.3.0' # Requires Ruby 2.x on/after this version
|
17
16
|
end
|
18
17
|
|
19
18
|
if RUBY_VERSION =~ /^1\./
|
@@ -21,14 +20,13 @@ if RUBY_VERSION =~ /^1\./
|
|
21
20
|
gem 'json', '< 2.0' # The 'json' gem drops pre-Ruby 2.x support on/after this version
|
22
21
|
gem 'term-ansicolor', '< 1.4' # The 'term-ansicolor' gem requires Ruby 2.x on/after this version
|
23
22
|
gem 'unf_ext', '< 0.0.7.3' # Requires Ruby 2.x on/after this version
|
24
|
-
|
25
|
-
if RbConfig::CONFIG['host_os'].downcase =~ /mswin|msys|mingw32/
|
26
|
-
gem 'ffi', '< 1.9.15' # The 'ffi' gem, for Windows, requires Ruby 2.x on/after this version
|
27
|
-
end
|
28
23
|
end
|
29
24
|
|
30
25
|
if RUBY_VERSION =~ /^2\.[23456789]/
|
31
26
|
gem 'test-unit'
|
27
|
+
# Cucumber 4.x uses the `cucumber-gherkin` gem, which is incompatible with
|
28
|
+
# the `gherkin` gem, upon which the `cuke_modeler` gem depends
|
29
|
+
gem 'cucumber', '< 4.0'
|
32
30
|
end
|
33
31
|
|
34
32
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec :path => "../../"
|
4
|
+
|
5
|
+
|
6
|
+
# cql can play with pretty much any version of these but they all play differently with Ruby
|
7
|
+
if RUBY_VERSION =~ /^1\.8/
|
8
|
+
gem 'cucumber', '< 1.3.0'
|
9
|
+
gem 'gherkin', '< 2.12.0'
|
10
|
+
gem 'rainbow', '< 2.0' # Ruby 1.8.x support dropped after this version
|
11
|
+
gem 'rake', '< 11.0' # Rake dropped 1.8.x support after this version
|
12
|
+
elsif RUBY_VERSION =~ /^1\./
|
13
|
+
gem 'cucumber', '< 2.0.0'
|
14
|
+
gem 'mime-types', '< 3.0.0' # Requires Ruby 2.x on/after this version
|
15
|
+
gem 'rake', '< 12.3.0' # Requires Ruby 2.x on/after this version
|
16
|
+
end
|
17
|
+
|
18
|
+
if RUBY_VERSION =~ /^1\./
|
19
|
+
gem 'tins', '< 1.7' # The 'tins' gem requires Ruby 2.x on/after this version
|
20
|
+
gem 'json', '< 2.0' # The 'json' gem drops pre-Ruby 2.x support on/after this version
|
21
|
+
gem 'term-ansicolor', '< 1.4' # The 'term-ansicolor' gem requires Ruby 2.x on/after this version
|
22
|
+
gem 'unf_ext', '< 0.0.7.3' # Requires Ruby 2.x on/after this version
|
23
|
+
end
|
24
|
+
|
25
|
+
if RUBY_VERSION =~ /^2\.[23456789]/
|
26
|
+
gem 'test-unit'
|
27
|
+
# Cucumber 4.x uses the `cucumber-gherkin` gem, which is incompatible with
|
28
|
+
# the `gherkin` gem, upon which the `cuke_modeler` gem depends
|
29
|
+
gem 'cucumber', '< 4.0'
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
gem 'cuke_modeler', '~> 2.0'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec :path => "../../"
|
4
|
+
|
5
|
+
# Cueumber 4.x doesn't work on all JRubies and this is the only earlier version
|
6
|
+
# that is compatible with the `cucumber-gherkin` gem, upon which CukeModler 3.x depends
|
7
|
+
gem 'cucumber', '2.2.0'
|
8
|
+
|
9
|
+
# The version of CukeModeler being tested
|
10
|
+
gem 'cuke_modeler', '~> 3.0'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module CQL
|
2
|
+
module HelperMethods
|
3
|
+
|
4
|
+
def cuke_modeler?(*versions)
|
5
|
+
versions.include?(cuke_modeler_major_version)
|
6
|
+
end
|
7
|
+
|
8
|
+
def cuke_modeler_major_version
|
9
|
+
Gem.loaded_specs['cuke_modeler'].version.version.match(/^(\d+)\./)[1].to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CQL
|
2
|
+
module ModelHelper
|
3
|
+
|
4
|
+
def directory_with(*models)
|
5
|
+
directory_model = CukeModeler::Directory.new
|
6
|
+
|
7
|
+
models.each do |model|
|
8
|
+
case
|
9
|
+
when model.is_a?(CukeModeler::Feature)
|
10
|
+
file_model = CukeModeler::FeatureFile.new
|
11
|
+
|
12
|
+
if cuke_modeler?(0)
|
13
|
+
file_model.features = [model]
|
14
|
+
else
|
15
|
+
file_model.feature = model
|
16
|
+
end
|
17
|
+
|
18
|
+
directory_model.feature_files << file_model
|
19
|
+
else
|
20
|
+
raise(ArgumentError, "Don't know how to handle a '#{model.class}'")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
directory_model
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
#TODO - add some specs for the 'as' clause
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../spec_helper"
|
2
|
+
|
3
|
+
|
4
|
+
describe 'an object that uses the DSL' do
|
5
|
+
|
6
|
+
|
7
|
+
let(:nodule) { CQL::Dsl }
|
8
|
+
let(:dsl_enabled_object) { Object.new.extend(nodule) }
|
9
|
+
|
10
|
+
|
11
|
+
describe "from" do
|
12
|
+
|
13
|
+
it 'knows from what to select attributes' do
|
14
|
+
expect(dsl_enabled_object).to respond_to(:from)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'selects from one or more things' do
|
18
|
+
expect(dsl_enabled_object.method(:from).arity).to eq(-1)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can handle an empty 'from' clause" do
|
22
|
+
gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
|
23
|
+
|
24
|
+
result = gs.query do
|
25
|
+
select name
|
26
|
+
from
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(result).to eq([])
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "multiple targets" do
|
33
|
+
|
34
|
+
it 'raises an exception for inapplicable attributes' do
|
35
|
+
gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
|
36
|
+
|
37
|
+
expect {
|
38
|
+
gs.query do
|
39
|
+
select name, steps
|
40
|
+
from features
|
41
|
+
from scenarios
|
42
|
+
end
|
43
|
+
}.to raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'shorthand' do
|
49
|
+
|
50
|
+
it 'should consider an exact match over a pluralization' do
|
51
|
+
plural_class_model = CukeModeler::CqlTestModels.new
|
52
|
+
singular_class_model = CukeModeler::CqlTestModel.new
|
53
|
+
|
54
|
+
plural_class_model.attribute_1 = 'plural'
|
55
|
+
singular_class_model.attribute_1 = 'singular'
|
56
|
+
plural_class_model.children << singular_class_model
|
57
|
+
|
58
|
+
repo = CQL::Repository.new(plural_class_model)
|
59
|
+
|
60
|
+
result = repo.query do
|
61
|
+
select attribute_1
|
62
|
+
from cql_test_model
|
63
|
+
end
|
64
|
+
|
65
|
+
expect(result.first['attribute_1']).to eq('singular')
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'raises an exception if the shorthand form of a class cannot be mapped to a real class' do
|
69
|
+
gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
|
70
|
+
|
71
|
+
expect {
|
72
|
+
gs.query do
|
73
|
+
select name
|
74
|
+
from not_a_real_class
|
75
|
+
end
|
76
|
+
}.to raise_error(ArgumentError, "Class 'CukeModeler::NotARealClass' does not exist")
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'can freely mix shorthand and long-form names' do
|
81
|
+
gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
|
82
|
+
|
83
|
+
# All long-form
|
84
|
+
base_result = gs.query do
|
85
|
+
select name
|
86
|
+
from CukeModeler::Scenario, CukeModeler::Feature
|
87
|
+
end
|
88
|
+
|
89
|
+
# All shorthand
|
90
|
+
expect(
|
91
|
+
gs.query do
|
92
|
+
select name
|
93
|
+
from scenarios, features
|
94
|
+
end
|
95
|
+
).to eq(base_result)
|
96
|
+
|
97
|
+
# A mix of both
|
98
|
+
expect(
|
99
|
+
gs.query do
|
100
|
+
select name
|
101
|
+
from CukeModeler::Scenario, features
|
102
|
+
end
|
103
|
+
).to eq(base_result)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
describe 'special scopes' do
|
110
|
+
|
111
|
+
it 'understands the :all scope' do
|
112
|
+
gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
|
113
|
+
|
114
|
+
expect { gs.query do
|
115
|
+
select :model
|
116
|
+
from :all
|
117
|
+
end
|
118
|
+
}.to_not raise_error
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'queries from all models when scoped to :all' do
|
122
|
+
model_1 = CukeModeler::CqlTestModel.new
|
123
|
+
model_2 = CukeModeler::CqlTestModel.new
|
124
|
+
model_3 = CukeModeler::CqlTestModel.new
|
125
|
+
|
126
|
+
model_1.children << model_2
|
127
|
+
model_1.children << model_3
|
128
|
+
|
129
|
+
repo = CQL::Repository.new(model_1)
|
130
|
+
|
131
|
+
result = repo.query do
|
132
|
+
select :model
|
133
|
+
from :all
|
134
|
+
end
|
135
|
+
|
136
|
+
expect(result).to match_array([{:model => model_1},
|
137
|
+
{:model => model_2},
|
138
|
+
{:model => model_3}])
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
end
|