cql 1.2.1 → 1.3.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cql.rb +18 -11
  3. data/lib/cql/dsl.rb +14 -2
  4. data/lib/cql/filters.rb +12 -6
  5. data/lib/cql/map_reduce.rb +29 -11
  6. data/lib/cql/model_dsl.rb +18 -0
  7. data/lib/cql/queriable.rb +14 -0
  8. data/lib/cql/sso_filters.rb +3 -2
  9. data/lib/cql/version.rb +1 -1
  10. data/testing/cql_test_model.rb +42 -0
  11. data/testing/cucumber/features/clauses/as_clause.feature +136 -0
  12. data/testing/cucumber/features/clauses/from_clause.feature +126 -0
  13. data/testing/cucumber/features/clauses/select_clause.feature +117 -0
  14. data/testing/cucumber/features/clauses/transform_clause.feature +153 -0
  15. data/testing/cucumber/features/clauses/with_clause.feature +363 -0
  16. data/testing/cucumber/features/dsl.feature +77 -0
  17. data/testing/cucumber/features/model_querying.feature +18 -0
  18. data/testing/cucumber/features/repository.feature +23 -0
  19. data/testing/cucumber/step_definitions/query_steps.rb +7 -0
  20. data/testing/cucumber/step_definitions/setup_steps.rb +25 -0
  21. data/testing/cucumber/step_definitions/verification_steps.rb +78 -0
  22. data/testing/cucumber/support/env.rb +24 -0
  23. data/testing/cucumber/support/transforms.rb +3 -0
  24. data/testing/fixtures/features/combined/a/f1_4_scenarios_5_so.feature +59 -0
  25. data/testing/fixtures/features/combined/a/f2_7_scenarios_2_so.feature +43 -0
  26. data/testing/fixtures/features/combined/a/f3_2_scenarios_3_so.feature +30 -0
  27. data/testing/fixtures/features/combined/b/f1_1_tag.feature +6 -0
  28. data/testing/fixtures/features/combined/b/f2_2_tags.feature +6 -0
  29. data/testing/fixtures/features/combined/b/f3_3_tags.feature +6 -0
  30. data/testing/fixtures/features/examples/basic/test_with_scenarios.feature +15 -0
  31. data/testing/fixtures/features/examples/filters/tag_count/simple.feature +21 -0
  32. data/testing/fixtures/features/examples/filters/tag_count/simple2.feature +21 -0
  33. data/testing/fixtures/features/examples/filters/tags/simple.feature +34 -0
  34. data/testing/fixtures/features/examples/filters/tags2/simple.feature +34 -0
  35. data/testing/fixtures/features/examples/filters/tags2/simple2.feature +34 -0
  36. data/testing/fixtures/features/examples/multiple_examples/test_with_scenarios.feature +43 -0
  37. data/testing/fixtures/features/examples/name_filter/name.feature +19 -0
  38. data/testing/fixtures/features/got/Lannisters.feature +24 -0
  39. data/testing/fixtures/features/got/Starks.feature +18 -0
  40. data/testing/fixtures/features/scen_outlines/basic/test_with_scenarios.feature +15 -0
  41. data/testing/fixtures/features/scen_outlines/filters/tag_count/simple.feature +21 -0
  42. data/testing/fixtures/features/scen_outlines/filters/tag_count/simple2.feature +21 -0
  43. data/testing/fixtures/features/scen_outlines/filters/tags/simple.feature +34 -0
  44. data/testing/fixtures/features/scen_outlines/filters/tags2/simple.feature +34 -0
  45. data/testing/fixtures/features/scen_outlines/filters/tags2/simple2.feature +34 -0
  46. data/testing/fixtures/features/scen_outlines/line_count/simple.feature +12 -0
  47. data/testing/fixtures/features/scen_outlines/line_count/simple2.feature +16 -0
  48. data/testing/fixtures/features/scen_outlines/line_filter/ll.feature +13 -0
  49. data/testing/fixtures/features/scen_outlines/multiple_examples/test_with_scenarios.feature +43 -0
  50. data/testing/fixtures/features/scen_outlines/name_filter/name.feature +19 -0
  51. data/testing/fixtures/features/scenario/line_count/simple.feature +9 -0
  52. data/testing/fixtures/features/scenario/line_count/simple2.feature +12 -0
  53. data/testing/fixtures/features/scenario/line_filter/ll.feature +9 -0
  54. data/testing/fixtures/features/scenario/name_filter/name.feature +13 -0
  55. data/testing/fixtures/features/scenario/simple/simple.feature +8 -0
  56. data/testing/fixtures/features/scenario/simple/test.feature +9 -0
  57. data/testing/fixtures/features/scenario/simple/test2.feature +5 -0
  58. data/testing/fixtures/features/scenario/simple/test_full.feature +22 -0
  59. data/testing/fixtures/features/scenario/simple2/test_full.feature +23 -0
  60. data/testing/fixtures/features/scenario/table/simple.feature +11 -0
  61. data/testing/fixtures/features/scenario/tag_count/simple.feature +17 -0
  62. data/testing/fixtures/features/scenario/tag_count/simple2.feature +17 -0
  63. data/testing/fixtures/features/scenario/tagged_features/simple.feature +8 -0
  64. data/testing/fixtures/features/scenario/tagged_features/test.feature +10 -0
  65. data/testing/fixtures/features/scenario/tagged_features/test2.feature +6 -0
  66. data/testing/fixtures/features/scenario/tagged_features/test_full.feature +22 -0
  67. data/testing/fixtures/features/scenario/tags/simple.feature +24 -0
  68. data/testing/fixtures/features/scenario/tags2/simple.feature +24 -0
  69. data/testing/fixtures/features/scenario/tags2/simple2.feature +24 -0
  70. data/testing/fixtures/features/scenario/tags3/simple.feature +21 -0
  71. data/testing/gemfiles/cuke_modeler0.gemfile +30 -0
  72. data/testing/gemfiles/cuke_modeler1.gemfile +30 -0
  73. data/testing/rspec/spec/dsl_spec.rb +600 -0
  74. data/testing/rspec/spec/filter_example_spec.rb +65 -0
  75. data/testing/rspec/spec/filter_feature_dsl_spec.rb +286 -0
  76. data/testing/rspec/spec/filter_sso_spec.rb +202 -0
  77. data/testing/rspec/spec/line_count_filterable_specs.rb +74 -0
  78. data/testing/rspec/spec/line_filterable_specs.rb +52 -0
  79. data/testing/rspec/spec/map_reduce_spec.rb +135 -0
  80. data/testing/rspec/spec/model_query_spec.rb +49 -0
  81. data/testing/rspec/spec/multiple_queries_spec.rb +24 -0
  82. data/testing/rspec/spec/name_filterable_specs.rb +52 -0
  83. data/testing/rspec/spec/queriable_specs.rb +45 -0
  84. data/testing/rspec/spec/repository_spec.rb +82 -0
  85. data/testing/rspec/spec/select_feature_dsl_spec.rb +114 -0
  86. data/testing/rspec/spec/select_scen_outline_dsl_spec.rb +234 -0
  87. data/testing/rspec/spec/select_scenario_dsl_spec.rb +132 -0
  88. data/testing/rspec/spec/spec_helper.rb +42 -0
  89. data/testing/rspec/spec/tag_filterable_specs.rb +107 -0
  90. metadata +170 -5
@@ -0,0 +1,77 @@
1
+ Feature: DSL
2
+
3
+ The cql gem uses a DSL to specify queries on a repository object that holds the models which represent a Cucumber test suite. The DSL can query for any attribute that is available on the underlying models.
4
+
5
+ Sample usage:
6
+ cql_repo.query do
7
+ select name, source_line
8
+ from features
9
+ end
10
+
11
+ Query results are returned as a list of attribute mappings for all of the models found in the repository. The sample query above might return:
12
+
13
+ [{'name' => 'Feature 1', 'source_line' => 1},
14
+ {'name' => 'Feature 2', 'source_line' => 3},
15
+ {'name' => 'Feature 3', 'source_line' => 10}]
16
+
17
+
18
+ Background: A sample Cucumber suite
19
+ Given a directory "test_directory"
20
+ And a file "test_directory/test_file_1.feature":
21
+ """
22
+ Feature: A test feature
23
+
24
+ Scenario: Test 1
25
+ * some steps
26
+
27
+ @special_tag
28
+ Scenario: Test 2
29
+ * some other steps
30
+
31
+ Scenario Outline: Test 3
32
+ * some steps
33
+ Examples: First examples
34
+ | param |
35
+ | value |
36
+ Examples: Second examples
37
+ | param |
38
+ | value |
39
+ """
40
+ And a repository is made from "test_directory"
41
+
42
+ Scenario: Automatic string conversion
43
+
44
+ Although most times it is unnecessary, using full strings in a query can remove syntactical ambiguity.
45
+
46
+ When the following query is executed:
47
+ """
48
+ select name
49
+ from scenarios
50
+ """
51
+ Then the result is the same as the result of the following query:
52
+ """
53
+ select 'name'
54
+ from 'scenarios'
55
+ """
56
+
57
+
58
+ # Commented out so that they aren't picked up by Relish
59
+ #
60
+ # @wip
61
+ # Scenario: Use 'order_by' to sort the results
62
+ #
63
+ # # 'and' is a keyword. Some other kind of repeater word would be needed
64
+ # @wip
65
+ # Scenario: 'And' can be used instead of repeating the previous keyword
66
+ # When the following query is executed:
67
+ # """
68
+ # select 'name'
69
+ # and 'source_line'
70
+ # from CukeModeler::Scenario
71
+ # and CukeModeler::Outline
72
+ # """
73
+ # Then the following values are returned:
74
+ # | name | source_line |
75
+ # | Test 1 | 3 |
76
+ # | Test 2 | 6 |
77
+ # | Test 3 | 9 |
@@ -0,0 +1,18 @@
1
+ Feature: Models can be queried directly
2
+
3
+ Note: This feature is only available with newer versions of the 'cuke_modeler' library.
4
+
5
+ @cuke_modeler_1x
6
+ Scenario: Querying a model
7
+ Given the models provided by CukeModeler
8
+ Then all of them can be queried
9
+ """
10
+ model = <model_class>.new
11
+
12
+ model.query do
13
+
14
+ select
15
+ from :all
16
+
17
+ end
18
+ """
@@ -0,0 +1,23 @@
1
+ Feature: Repository
2
+
3
+ All queries are performed against a repository object. A repository is simply a collection of models that represent a Cucumber test suite. Commonly, a repository is created based on a file path that is the location of such a test suite. However, repositories can also be created using any model as their starting point.
4
+
5
+
6
+ Scenario: Using a file path to create a repository
7
+ Given a directory "path/to/test_directory"
8
+ Then the following code executes without error:
9
+ """
10
+ CQL::Repository.new("path/to/test_directory")
11
+ """
12
+
13
+ Scenario: Using a model to create a repository
14
+
15
+ Note: Non-directory models can also be used
16
+
17
+ Given a directory "path/to/test_directory"
18
+ Then the following code executes without error:
19
+ """
20
+ directory_model = CukeModeler::Directory.new("path/to/test_directory")
21
+
22
+ CQL::Repository.new(directory_model)
23
+ """
@@ -0,0 +1,7 @@
1
+ When(/^the following query is executed:$/) do |query_text|
2
+ command = "@repository.query do
3
+ #{query_text}
4
+ end"
5
+
6
+ @query_results = eval(command)
7
+ end
@@ -0,0 +1,25 @@
1
+ Given(/^a directory "([^"]*)"$/) do |partial_directory_path|
2
+ directory_path = partial_directory_path.include?('path/to') ? process_path(partial_directory_path) : "#{@default_file_directory}/#{partial_directory_path}"
3
+
4
+ FileUtils.mkpath(directory_path) unless File.exists?(directory_path)
5
+ end
6
+
7
+ And(/^a file "([^"]*)":$/) do |partial_file_path, file_text|
8
+ File.open("#{@default_file_directory}/#{partial_file_path}", 'w') { |file| file.write file_text }
9
+ end
10
+
11
+ And(/^a repository is made from "([^"]*)"$/) do |partial_path|
12
+ repo_path = "#{@default_file_directory}/#{partial_path}"
13
+
14
+ @repository = CQL::Repository.new(repo_path)
15
+ end
16
+
17
+ Given(/^the models provided by CukeModeler$/) do
18
+ @available_model_classes = Array.new.tap do |classes|
19
+ CukeModeler.constants.each do |constant|
20
+ if CukeModeler.const_get(constant).is_a?(Class)
21
+ classes << CukeModeler.const_get(constant) if CukeModeler.const_get(constant).ancestors.include?(CukeModeler::Model)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,78 @@
1
+ Then(/^the following values are returned:$/) do |values|
2
+ expected_results = values.hashes
3
+ expected_results.each { |result| result['source_line'] = result['source_line'].to_i if result['source_line'] }
4
+ expected_results.each { |result| result['scenario_line'] = result['scenario_line'].to_i if result['scenario_line'] }
5
+ expected_results.each { |result| result['tags'] = eval(result['tags']) if result['tags'] }
6
+ expected_results.each { |result| result['scenario_tags'] = eval(result['scenario_tags']) if result['scenario_tags'] }
7
+
8
+ expected_results.each do |result|
9
+ result.each_pair { |key, value| result[key] = value.sub('path/to', @default_file_directory) if value =~ /path\/to/ }
10
+ end
11
+
12
+ expect(@query_results).to match_array(expected_results)
13
+ end
14
+
15
+ # Then(/^all of them can be queried for additional information$/) do
16
+ #
17
+ # expect(@cm_models).to_not be_empty
18
+ #
19
+ # @cm_models.each do |model|
20
+ # raise("Expected #{model} to define :query") unless model.method_defined?(:query)
21
+ # end
22
+ #
23
+ # end
24
+
25
+ Then(/^the models for the following items are returned:$/) do |item_names|
26
+ expected_results = item_names.raw.flatten
27
+
28
+ expect(@query_results.collect { |result| result[:self].name }).to match_array(expected_results)
29
+ end
30
+
31
+ Then(/^the result is the same as the result of the following query:$/) do |query_text|
32
+ command = "@repository.query do
33
+ #{query_text}
34
+ end"
35
+
36
+ baseline_results = eval(command)
37
+
38
+ expect(@query_results).to eq(baseline_results)
39
+ end
40
+
41
+ Then(/^the following code executes without error:$/) do |code_text|
42
+ code_text = process_path(code_text)
43
+
44
+ expect { eval(code_text) }.to_not raise_error
45
+ end
46
+
47
+ Then(/^all of them can be queried$/) do |code_text|
48
+ @available_model_classes.each do |clazz|
49
+ code_text.gsub!('<model_class>', clazz.to_s)
50
+
51
+ expect(clazz.new).to respond_to(:query)
52
+
53
+ # Make sure that the example code is valid
54
+ expect { eval(code_text) }.to_not raise_error
55
+ end
56
+ end
57
+
58
+ Then(/^all models are queried from$/) do
59
+ # Just making sure that multiple model results are returned
60
+ expect(@query_results.count).to be > 1
61
+
62
+ @query_results.each do |result|
63
+ class_name = result[:model].class.name.split('::').last
64
+
65
+ expect(CukeModeler.const_defined?(class_name)).to be true
66
+ end
67
+ end
68
+
69
+ And(/^equivalent results are returned for the following query:$/) do |query_text|
70
+ command = "@repository.query do
71
+ #{query_text}
72
+ end"
73
+
74
+ alternate_results = eval(command)
75
+
76
+ # Only checking the values of the results because they will have different :model/:self keys
77
+ expect(alternate_results.collect { |result| result.values }).to eq(@query_results.collect { |result| result.values })
78
+ end
@@ -0,0 +1,24 @@
1
+ unless RUBY_VERSION.to_s < '1.9.0'
2
+ require 'simplecov'
3
+ SimpleCov.command_name('cql-cucumber')
4
+ end
5
+
6
+
7
+ require 'cql'
8
+ require 'cql/model_dsl'
9
+
10
+
11
+ Before do
12
+ @default_file_directory = "#{File.dirname(__FILE__)}/../temp_files"
13
+
14
+ FileUtils.mkdir(@default_file_directory)
15
+ end
16
+
17
+ After do
18
+ FileUtils.remove_dir(@default_file_directory, true)
19
+ end
20
+
21
+
22
+ def process_path(path)
23
+ path.sub('path/to', @default_file_directory)
24
+ end
@@ -0,0 +1,3 @@
1
+ Transform /^(-?\d+)$/ do |number|
2
+ number.to_i
3
+ end
@@ -0,0 +1,59 @@
1
+ Feature: f1_4_scenarios_5_so
2
+ (4 scenarios, 5 scenario outlines)
3
+
4
+ Scenario: A cat in a hat
5
+ Given A cat in a hat
6
+ And walked across the road
7
+ Then he was on the other side
8
+
9
+ Scenario: The lonely giant
10
+ Given he was very big
11
+ And he was an orphan
12
+ And no one wanted to play with him
13
+ And he couldn't fit into normal sized building
14
+ Then he was all alone
15
+
16
+ Scenario: The king of kings
17
+ Given king "George"
18
+ And king "Bruce"
19
+ Then George is the king of kings
20
+
21
+ Scenario: A deer
22
+ * A deer
23
+ * A female deer
24
+ * Ray, a drop of golden sun
25
+
26
+ Scenario Outline: f1_so1
27
+ Given blah <e>
28
+
29
+ Examples:
30
+ | e |
31
+ | r |
32
+
33
+ Scenario Outline: f1_so2
34
+ Given blah <e>
35
+
36
+ Examples:
37
+ | e |
38
+ | r |
39
+
40
+ Scenario Outline: f1_so3
41
+ Given blah <e>
42
+
43
+ Examples:
44
+ | e |
45
+ | r |
46
+
47
+ Scenario Outline: f1_so4
48
+ Given blah <e>
49
+
50
+ Examples:
51
+ | e |
52
+ | r |
53
+
54
+ Scenario Outline: f1_so5
55
+ Given blah <e>
56
+
57
+ Examples:
58
+ | e |
59
+ | r |
@@ -0,0 +1,43 @@
1
+ Feature: f2_7_scenarios_2_so
2
+
3
+ Scenario: f2_scen1
4
+ Given Something
5
+ Then something else
6
+
7
+ Scenario: f2_scen2
8
+ Given Something
9
+ Then something else
10
+
11
+ Scenario: f2_scen3
12
+ Given Something
13
+ Then something else
14
+
15
+ Scenario: f2_scen4
16
+ Given Something
17
+ Then something else
18
+
19
+ Scenario: f2_scen5
20
+ Given Something
21
+ Then something else
22
+
23
+ Scenario: f2_scen6
24
+ Given Something
25
+ Then something else
26
+
27
+ Scenario: f2_scen7
28
+ Given Something
29
+ Then something else
30
+
31
+ Scenario Outline: f2_so1
32
+ Given blah <e>
33
+
34
+ Examples:
35
+ | e |
36
+ | r |
37
+
38
+ Scenario Outline: f2_so2
39
+ Given blah <e>
40
+
41
+ Examples:
42
+ | e |
43
+ | r |
@@ -0,0 +1,30 @@
1
+ Feature: f3_2_scenarios_3_so
2
+
3
+ Scenario: f3_scen1
4
+ Given Something
5
+ Then something else
6
+
7
+ Scenario: f3_scen2
8
+ Given Something
9
+ Then something else
10
+
11
+ Scenario Outline: f3_so1
12
+ Given blah <e>
13
+
14
+ Examples:
15
+ | e |
16
+ | r |
17
+
18
+ Scenario Outline: f3_so2
19
+ Given blah <e>
20
+
21
+ Examples:
22
+ | e |
23
+ | r |
24
+
25
+ Scenario Outline: f3_so3
26
+ Given blah <e>
27
+
28
+ Examples:
29
+ | e |
30
+ | r |
@@ -0,0 +1,6 @@
1
+ @one
2
+ Feature: f1_1_tag
3
+
4
+ Scenario: f1_scen1
5
+ Given Something
6
+ Then something else
@@ -0,0 +1,6 @@
1
+ @one @two
2
+ Feature: f2_2_tags
3
+
4
+ Scenario: f2_scen1
5
+ Given Something
6
+ Then something else
@@ -0,0 +1,6 @@
1
+ @one @two @three
2
+ Feature: f3_3_tags
3
+
4
+ Scenario: f3_scen1
5
+ Given Something
6
+ Then something else
@@ -0,0 +1,15 @@
1
+ Feature: Test Feature
2
+
3
+ Scenario Outline: An Outline
4
+ Given something happend
5
+ Then I expect something else
6
+ Examples:
7
+ | var_a | var_b |
8
+ | 1 | a |
9
+ | 2 | b |
10
+ | 3 | c |
11
+ | 4 | d |
12
+
13
+ Scenario: A Scenario
14
+ Given something happend
15
+ Then I expect something else
@@ -0,0 +1,21 @@
1
+ Feature: Simple
2
+
3
+ Scenario Outline:
4
+ Given Something
5
+ | a | a |
6
+ | s | a |
7
+ | s | s |
8
+ Then something else
9
+ @one
10
+ Examples: 1 tag
11
+ | param |
12
+
13
+ Scenario Outline:
14
+ Given Something
15
+ | a | a |
16
+ | s | a |
17
+ | s | s |
18
+ Then something else
19
+ @one @two
20
+ Examples: 2 tags
21
+ | param |