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.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/lib/cql.rb +4 -169
  3. data/lib/cql/dsl.rb +39 -5
  4. data/lib/cql/feature_filters.rb +2 -0
  5. data/lib/cql/filters.rb +25 -1
  6. data/lib/cql/map_reduce.rb +3 -0
  7. data/lib/cql/model_dsl.rb +7 -1
  8. data/lib/cql/queriable.rb +6 -1
  9. data/lib/cql/query.rb +157 -0
  10. data/lib/cql/repository.rb +25 -0
  11. data/lib/cql/sso_filters.rb +4 -0
  12. data/lib/cql/version.rb +2 -1
  13. data/testing/cucumber/features/clauses/as_clause.feature +10 -9
  14. data/testing/cucumber/features/clauses/from_clause.feature +15 -20
  15. data/testing/cucumber/features/clauses/predefined_with_filters.feature +392 -0
  16. data/testing/cucumber/features/clauses/select_clause.feature +11 -14
  17. data/testing/cucumber/features/clauses/transform_clause.feature +10 -9
  18. data/testing/cucumber/features/clauses/with_clause.feature +10 -170
  19. data/testing/cucumber/features/dsl.feature +15 -34
  20. data/testing/cucumber/step_definitions/setup_steps.rb +1 -13
  21. data/testing/cucumber/step_definitions/verification_steps.rb +6 -7
  22. data/testing/cucumber/support/env.rb +9 -9
  23. data/testing/gemfiles/cuke_modeler0.gemfile +10 -7
  24. data/testing/gemfiles/cuke_modeler1.gemfile +6 -7
  25. data/testing/gemfiles/cuke_modeler2.gemfile +33 -0
  26. data/testing/gemfiles/cuke_modeler3.gemfile +10 -0
  27. data/testing/helper_methods.rb +13 -0
  28. data/testing/model_helper.rb +28 -0
  29. data/testing/rspec/spec/clauses/as_clause_spec.rb +1 -0
  30. data/testing/rspec/spec/clauses/from_clause_spec.rb +146 -0
  31. data/testing/rspec/spec/clauses/select_clause_spec.rb +184 -0
  32. data/testing/rspec/spec/clauses/transform_clause_spec.rb +35 -0
  33. data/testing/rspec/spec/clauses/with_clause_spec.rb +84 -0
  34. data/testing/rspec/spec/clauses/without_clause_spec.rb +171 -0
  35. data/testing/rspec/spec/cql_spec.rb +25 -0
  36. data/testing/rspec/spec/dsl_spec.rb +3 -575
  37. data/testing/rspec/spec/filter_example_spec.rb +1 -1
  38. data/testing/rspec/spec/filter_feature_dsl_spec.rb +13 -13
  39. data/testing/rspec/spec/filter_sso_spec.rb +2 -2
  40. data/testing/rspec/spec/line_filterable_specs.rb +1 -1
  41. data/testing/rspec/spec/map_reduce_spec.rb +1 -1
  42. data/testing/rspec/spec/model_query_spec.rb +1 -1
  43. data/testing/rspec/spec/multiple_queries_spec.rb +1 -1
  44. data/testing/rspec/spec/name_filterable_specs.rb +1 -1
  45. data/testing/rspec/spec/predefined_filters_spec.rb +284 -0
  46. data/testing/rspec/spec/repository_spec.rb +3 -3
  47. data/testing/rspec/spec/select_feature_dsl_spec.rb +8 -8
  48. data/testing/rspec/spec/select_scen_outline_dsl_spec.rb +14 -14
  49. data/testing/rspec/spec/select_scenario_dsl_spec.rb +9 -9
  50. data/testing/rspec/spec/spec_helper.rb +7 -17
  51. metadata +52 -23
  52. data/testing/cucumber/support/transforms.rb +0 -3
@@ -7,27 +7,30 @@ 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 'mime-types', '< 2.0.0' # (For the relish gem) Ruby 1.8.x dropped somewhere in the 2.x series
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 'rest-client', '< 2.0.0' # Requires Ruby 2.x on/after this version
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\./
20
19
  gem 'tins', '< 1.7' # The 'tins' gem requires Ruby 2.x on/after this version
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
-
24
- if RbConfig::CONFIG['host_os'].downcase =~ /mswin|msys|mingw32/
25
- gem 'ffi', '< 1.9.15' # The 'ffi' gem, for Windows, requires Ruby 2.x on/after this version
26
- end
22
+ gem 'unf_ext', '< 0.0.7.3' # Requires Ruby 2.x on/after this version
27
23
  end
28
24
 
29
25
  if RUBY_VERSION =~ /^2\.[23456789]/
30
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'
31
34
  end
32
35
 
33
36
 
@@ -7,27 +7,26 @@ 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 'mime-types', '< 2.0.0' # (For the relish gem) Ruby 1.8.x dropped somewhere in the 2.x series
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 'rest-client', '< 2.0.0' # Requires Ruby 2.x on/after this version
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\./
20
19
  gem 'tins', '< 1.7' # The 'tins' gem requires Ruby 2.x on/after this version
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
-
24
- if RbConfig::CONFIG['host_os'].downcase =~ /mswin|msys|mingw32/
25
- gem 'ffi', '< 1.9.15' # The 'ffi' gem, for Windows, requires Ruby 2.x on/after this version
26
- end
22
+ gem 'unf_ext', '< 0.0.7.3' # Requires Ruby 2.x on/after this version
27
23
  end
28
24
 
29
25
  if RUBY_VERSION =~ /^2\.[23456789]/
30
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'
31
30
  end
32
31
 
33
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
@@ -0,0 +1,184 @@
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
+ describe "select" do
11
+
12
+ it 'knows how to select attributes' do
13
+ expect(dsl_enabled_object).to respond_to(:select)
14
+ end
15
+
16
+ it 'selects one or more attributes' do
17
+ expect(dsl_enabled_object.method(:select).arity).to eq(-1)
18
+ end
19
+
20
+ it 'correctly selects a single attribute from a model' do
21
+ model = CukeModeler::CqlTestModel.new
22
+ model.attribute_1 = 'foo'
23
+
24
+ repo = CQL::Repository.new(model)
25
+
26
+ result = repo.query do
27
+ select attribute_1
28
+ from cql_test_model
29
+ end
30
+
31
+
32
+ expect(result).to eq([{'attribute_1' => 'foo'}])
33
+ end
34
+
35
+ it 'correctly selects multiple attributes from a model' do
36
+ model = CukeModeler::CqlTestModel.new
37
+ model.attribute_1 = 'foo'
38
+ model.attribute_2 = 'bar'
39
+
40
+ repo = CQL::Repository.new(model)
41
+
42
+ result = repo.query do
43
+ select attribute_1, attribute_2
44
+ from cql_test_model
45
+ end
46
+
47
+
48
+ expect(result).to eq([{'attribute_1' => 'foo',
49
+ 'attribute_2' => 'bar'}])
50
+ end
51
+
52
+
53
+ describe 'special attributes' do
54
+
55
+ it 'understands the :model attribute' do
56
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
57
+
58
+ expect { gs.query do
59
+ select :model
60
+ from features
61
+ end
62
+ }.to_not raise_error
63
+ end
64
+
65
+ it 'interprets :model in the same manner that it interprets :self' do
66
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
67
+
68
+ self_result = gs.query do
69
+ select :self
70
+ from features
71
+ end
72
+
73
+ model_result = gs.query do
74
+ select :model
75
+ from features
76
+ end
77
+
78
+ # Only checking the values of the results because they will have different :model/:self keys
79
+ expect(model_result.collect { |result| result.values }).to eq(self_result.collect { |result| result.values })
80
+ end
81
+
82
+ it 'complains if an unknown special attribute is queried' do
83
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
84
+
85
+ expect {
86
+ gs.query do
87
+ select :foo
88
+ from scenarios
89
+ end
90
+ }.to raise_error(ArgumentError, ":foo is not a valid attribute for selection.")
91
+ end
92
+
93
+ it 'uses the :self attribute by default' do
94
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
95
+
96
+ default_result = gs.query do
97
+ select
98
+ from features
99
+ end
100
+
101
+ self_result = gs.query do
102
+ select :self
103
+ from features
104
+ end
105
+
106
+ expect(self_result).to eq(default_result)
107
+ end
108
+
109
+ end
110
+
111
+
112
+ it 'complains if an unknown normal attribute is queried' do
113
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
114
+
115
+ expect {
116
+ gs.query do
117
+ select steps
118
+ from features
119
+ end
120
+ }.to raise_error(ArgumentError, "'steps' is not a valid attribute for selection from a 'CukeModeler::Feature'.")
121
+ end
122
+
123
+
124
+ describe "multiple selections" do
125
+
126
+ it 'can freely mix empty selections and attribute selections' do
127
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
128
+
129
+ base_result = gs.query do
130
+ select :self
131
+ select name
132
+ select :self
133
+ as 'foo', 'bar', 'baz'
134
+ from scenarios
135
+ end
136
+
137
+
138
+ expect(
139
+ gs.query do
140
+ select
141
+ select name
142
+ select
143
+ as 'foo', 'bar', 'baz'
144
+ from scenarios
145
+ end
146
+ ).to eq(base_result)
147
+ end
148
+
149
+ end
150
+
151
+
152
+ describe 'duplicate selections' do
153
+
154
+ let(:warning_message) { "Multiple selections made without using an 'as' clause\n" }
155
+
156
+ it "warns if the same attribute is selected more than once without an 'as' clause being used" do
157
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
158
+
159
+ expect {
160
+ gs.query do
161
+ select :model, :model, :model
162
+ from :all
163
+ end
164
+ }.to output(warning_message).to_stderr
165
+ end
166
+
167
+ it "does not warn if the same attribute is selected more than once and an 'as' clause is used" do
168
+ gs = CQL::Repository.new("#{CQL_FEATURE_FIXTURES_DIRECTORY}/scenario/simple")
169
+
170
+ expect {
171
+ gs.query do
172
+ select :model, :model, :model
173
+ # Usage of the clause is sufficient. Not going to try and count the mappings or anything like that.
174
+ as foo
175
+ from :all
176
+ end
177
+ }.to_not output(warning_message).to_stderr
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+
184
+ end