cuke_modeler 3.5.0 → 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -2
  3. data/LICENSE.txt +1 -1
  4. data/README.md +7 -7
  5. data/cuke_modeler.gemspec +15 -5
  6. data/lib/cuke_modeler.rb +0 -1
  7. data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +13 -0
  8. data/lib/cuke_modeler/adapters/gherkin_18_adapter.rb +24 -0
  9. data/lib/cuke_modeler/adapters/gherkin_19_adapter.rb +61 -0
  10. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +3 -3
  11. data/lib/cuke_modeler/containing.rb +17 -1
  12. data/lib/cuke_modeler/described.rb +0 -1
  13. data/lib/cuke_modeler/models/background.rb +0 -1
  14. data/lib/cuke_modeler/models/cell.rb +0 -1
  15. data/lib/cuke_modeler/models/comment.rb +0 -1
  16. data/lib/cuke_modeler/models/directory.rb +2 -3
  17. data/lib/cuke_modeler/models/doc_string.rb +0 -1
  18. data/lib/cuke_modeler/models/example.rb +0 -1
  19. data/lib/cuke_modeler/models/feature.rb +0 -1
  20. data/lib/cuke_modeler/models/feature_file.rb +0 -1
  21. data/lib/cuke_modeler/models/model.rb +0 -2
  22. data/lib/cuke_modeler/models/outline.rb +0 -1
  23. data/lib/cuke_modeler/models/row.rb +5 -1
  24. data/lib/cuke_modeler/models/rule.rb +8 -2
  25. data/lib/cuke_modeler/models/scenario.rb +0 -1
  26. data/lib/cuke_modeler/models/step.rb +0 -1
  27. data/lib/cuke_modeler/models/table.rb +0 -1
  28. data/lib/cuke_modeler/models/tag.rb +0 -1
  29. data/lib/cuke_modeler/named.rb +0 -1
  30. data/lib/cuke_modeler/nested.rb +0 -1
  31. data/lib/cuke_modeler/parsed.rb +0 -1
  32. data/lib/cuke_modeler/parsing.rb +22 -15
  33. data/lib/cuke_modeler/sourceable.rb +0 -1
  34. data/lib/cuke_modeler/stepped.rb +0 -1
  35. data/lib/cuke_modeler/taggable.rb +0 -1
  36. data/lib/cuke_modeler/version.rb +1 -1
  37. data/testing/cucumber/features/modeling/rule_modeling.feature +44 -2
  38. data/testing/cucumber/features/modeling/rule_output.feature +4 -0
  39. metadata +67 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba3e400ea68f67944c0c5bf170179fb50a60237e507d3113a921c844010f7d91
4
- data.tar.gz: 6224ca8ff2505acfb0415c82e9b1963ba5cf21573e2a9cac8857cb63171b288f
3
+ metadata.gz: d7821b738cb9b7436e38de701654c9ca04d087ba2e482f01af0600f86383b47d
4
+ data.tar.gz: 8b71afb721c52cc198243a468807547d45254dab84dd5bafcbec49e9bb4befb0
5
5
  SHA512:
6
- metadata.gz: a447530c96482e6464ad31151262e5a0fbfd11527445ae8965c834e6ece15ee33f89381eb2276d7ee043823ab491eaed932bb35f492bfdb2fe8a43defd605e37
7
- data.tar.gz: e8b05b052cad1f7395dec1e8da58bd84145c1699dce19b9bb261eb76bf29ceb1ebf3e7fa2cfe13773ff9f29f8c86d93543f9a5a34f79b1fc2fe402257618bbe7
6
+ metadata.gz: f114b4de2f4f2ef4ffd95078c7b8f72db2318174a75c4d4ed86a900ed21585e91e918afe97770afc1857b3cc80c904e471717f59a90c814bd7664575879e07e8
7
+ data.tar.gz: e870f0c73a8f296f6c8b108956d787586e9f47b3a2bff78db9a10db58c8df2ffc39fed04a1ace3629911c03f36ac6aee6c3e74475c60c58d7d0416f141d07037
data/CHANGELOG.md CHANGED
@@ -8,6 +8,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  Nothing yet...
10
10
 
11
+
12
+ ## [3.10.0] - 2021-05-28
13
+
14
+ ### Added
15
+ - Support added for more versions of the `cucumber-gherkin` gem
16
+ - 19.x
17
+
18
+ ### Fixed
19
+ - `Rule` models now clear out parsing data for their tags. This data was an unintentional duplication of the
20
+ parsing data that the `Tag` models already contained.
21
+
22
+
23
+ ## [3.9.0] - 2021-04-23
24
+
25
+ ### Added
26
+ - `Rule` models are now taggable elements
27
+
28
+
29
+ ## [3.8.0] - 2021-04-18
30
+
31
+ ### Added
32
+ - Support added for more versions of the `cucumber-gherkin` gem
33
+ - 18.x
34
+
35
+
36
+ ## [3.7.0] - 2021-02-18
37
+
38
+ ### Added
39
+ - Support added for more versions of the `cucumber-gherkin` gem
40
+ - 17.x
41
+
42
+
43
+ ## [3.6.0] - 2021-01-05
44
+
45
+ ### Added
46
+ - Ruby 3.x is now supported
47
+ - All models are now `Enumerable`. However, some methods such as `Enumerable#max` and `Enumerable#sort` do not work
48
+ because models do not meaningfully compare to each other.
49
+
50
+ ### Deprecated
51
+ - `Model#each_descendant` and `Model#each_model` will be removed on the next major release. `Model#each` and methods in
52
+ the `Enumerable` module now provide this kind of functionality.
53
+
54
+ ### Fixed
55
+ - `Row#children` now returns the row's `Cell` models instead of returning an empty array
56
+
57
+
11
58
  ## [3.5.0] - 2020-12-19
12
59
 
13
60
  ### Added
@@ -329,7 +376,7 @@ Nothing yet...
329
376
 
330
377
  ### Fixed
331
378
 
332
- - Fixed a bug that was causing object comparison using #== to not
379
+ - Fixed a bug that was causing object comparison using `#==` to not
333
380
  work when comparing some models to other types of objects.
334
381
 
335
382
 
@@ -340,7 +387,12 @@ Nothing yet...
340
387
  - Initial release
341
388
 
342
389
 
343
- [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.5.0...HEAD
390
+ [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.10.0...HEAD
391
+ [3.10.0]: https://github.com/enkessler/cuke_modeler/compare/v3.9.0...v3.10.0
392
+ [3.9.0]: https://github.com/enkessler/cuke_modeler/compare/v3.8.0...v3.9.0
393
+ [3.8.0]: https://github.com/enkessler/cuke_modeler/compare/v3.7.0...v3.8.0
394
+ [3.7.0]: https://github.com/enkessler/cuke_modeler/compare/v3.6.0...v3.7.0
395
+ [3.6.0]: https://github.com/enkessler/cuke_modeler/compare/v3.5.0...v3.6.0
344
396
  [3.5.0]: https://github.com/enkessler/cuke_modeler/compare/v3.4.0...v3.5.0
345
397
  [3.4.0]: https://github.com/enkessler/cuke_modeler/compare/v3.3.0...v3.4.0
346
398
  [3.3.0]: https://github.com/enkessler/cuke_modeler/compare/v3.2.0...v3.3.0
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2020 Eric Kessler, et al
1
+ Copyright (c) 2014-2021 Eric Kessler, et al
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -4,15 +4,15 @@ Basic stuff:
4
4
  [![Downloads](https://img.shields.io/gem/dt/cuke_modeler.svg)](https://rubygems.org/gems/cuke_modeler)
5
5
 
6
6
  User stuff:
7
- [![Cucumber Docs](http://img.shields.io/badge/Documentation-Features-green.svg)](https://app.cucumber.pro/projects/cuke_modeler)
7
+ [![Cucumber Docs](http://img.shields.io/badge/Documentation-Features-green.svg)](https://github.com/enkessler/cuke_modeler/tree/master/testing/cucumber/features)
8
8
  [![Yard Docs](http://img.shields.io/badge/Documentation-API-blue.svg)](https://www.rubydoc.info/gems/cuke_modeler)
9
9
 
10
10
  Developer stuff:
11
- [![Build Status](https://travis-ci.org/enkessler/cuke_modeler.svg)](https://travis-ci.org/enkessler/cuke_modeler)
12
- [![Build status](https://ci.appveyor.com/api/projects/status/is8xqvoqn3pjh9l0?svg=true)](https://ci.appveyor.com/project/enkessler/cuke-modeler)
13
- [![Coverage Status](https://coveralls.io/repos/github/enkessler/cuke_modeler/badge.svg)](https://coveralls.io/github/enkessler/cuke_modeler)
11
+ [![Build Status](https://travis-ci.org/enkessler/cuke_modeler.svg?branch=master)](https://travis-ci.org/enkessler/cuke_modeler)
12
+ [![Build status](https://ci.appveyor.com/api/projects/status/is8xqvoqn3pjh9l0/branch/master?svg=true)](https://ci.appveyor.com/project/enkessler/cuke-modeler)
13
+ [![Coverage Status](https://coveralls.io/repos/github/enkessler/cuke_modeler/badge.svg?branch=master)](https://coveralls.io/github/enkessler/cuke_modeler?branch=master)
14
14
  [![Maintainability](https://api.codeclimate.com/v1/badges/83986d8f7a918fed9707/maintainability)](https://codeclimate.com/github/enkessler/cuke_modeler/maintainability)
15
- [![Inline docs](http://inch-ci.org/github/enkessler/cuke_modeler.svg)](https://inch-ci.org/github/enkessler/cuke_modeler)
15
+ [![Inline docs](http://inch-ci.org/github/enkessler/cuke_modeler.svg?branch=master)](https://inch-ci.org/github/enkessler/cuke_modeler)
16
16
 
17
17
  ---
18
18
 
@@ -21,7 +21,7 @@ Developer stuff:
21
21
  There comes a time in every programmer's adventures with Cucumber when they
22
22
  want to do Really Cool Stuff with their tests. This usually necessitates
23
23
  scanning all of their feature files and playing with the output. While the
24
- **[cucumber-gherkin](https://github.com/cucumber/cucumber/tree/master/gherkin)** gem does a fine job of parsing feature files, reading or even manipulating
24
+ **[cucumber-gherkin](https://github.com/cucumber/cucumber/tree/master/gherkin)** gem ([previously](https://github.com/enkessler/cuke_modeler/blob/master/CHANGELOG.md#300---2020-06-08) just the `gherkin` gem) does a fine job of parsing feature files, reading or even manipulating
25
25
  the resulting Abstract Syntax Tree is not always fun. **cuke_modeler** comes to
26
26
  the rescue by providing a modeling layer that is easier to work with.
27
27
 
@@ -84,7 +84,7 @@ an entire test suite!
84
84
 
85
85
  For more information on the different models (which more or less have the same relation
86
86
  to each other as described in the AST [here](https://github.com/cucumber/cucumber/tree/master/gherkin#ast)) and how to use them, see the
87
- [documentation](https://app.cucumber.pro/projects/cuke_modeler).
87
+ [documentation](https://github.com/enkessler/cuke_modeler/tree/master/testing/cucumber/features).
88
88
 
89
89
  ## Modeling dialects other than English
90
90
 
data/cuke_modeler.gemspec CHANGED
@@ -13,10 +13,18 @@ Gem::Specification.new do |spec|
13
13
  "Abstract Syntax Tree that the 'cucumber-gherkin' gem generates when parsing features, ",
14
14
  'as well as providing models for feature files and directories in order to be able to ',
15
15
  "have a fully traversable model tree of a test suite's structure. These models can then ",
16
- 'be analyzed or manipulated more easily than the underlying AST layer.'].join("\n")
16
+ 'be analyzed or manipulated more easily than the underlying AST layer.'].join
17
17
  spec.homepage = 'https://github.com/enkessler/cuke_modeler'
18
18
  spec.license = 'MIT'
19
19
 
20
+ spec.metadata = {
21
+ 'bug_tracker_uri' => 'https://github.com/enkessler/cuke_modeler/issues',
22
+ 'changelog_uri' => 'https://github.com/enkessler/cuke_modeler/blob/master/CHANGELOG.md',
23
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/cuke_modeler',
24
+ 'homepage_uri' => 'https://github.com/enkessler/cuke_modeler',
25
+ 'source_code_uri' => 'https://github.com/enkessler/cuke_modeler'
26
+ }
27
+
20
28
  # Specify which files should be added to the gem when it is released.
21
29
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
30
  spec.files = Dir.chdir(File.expand_path('', __dir__)) do
@@ -26,15 +34,16 @@ Gem::Specification.new do |spec|
26
34
  end
27
35
  spec.require_paths = ['lib']
28
36
 
29
- spec.required_ruby_version = '>= 2.3', '< 3.0'
37
+ spec.required_ruby_version = '>= 2.3', '< 4.0'
30
38
 
31
- spec.add_runtime_dependency 'cucumber-gherkin', '< 17.0'
39
+ spec.add_runtime_dependency 'cucumber-gherkin', '< 20.0'
32
40
 
33
41
  spec.add_development_dependency 'bundler', '< 3.0'
42
+ spec.add_development_dependency 'childprocess', '< 5.0'
34
43
  spec.add_development_dependency 'coveralls', '< 1.0.0'
44
+ spec.add_development_dependency 'ffi', '< 2.0' # This is an invisible dependency for the `childprocess` gem on Windows
35
45
  # Cucumber 4.x is the earliest version to use cucumber-gherkin
36
- spec.add_development_dependency 'cucumber', '>= 4.0.0', '< 6.0.0'
37
- spec.add_development_dependency 'racatt', '~> 1.0'
46
+ spec.add_development_dependency 'cucumber', '>= 4.0.0', '< 7.0.0'
38
47
  spec.add_development_dependency 'rainbow', '< 4.0.0'
39
48
  spec.add_development_dependency 'rake', '< 14.0.0'
40
49
  spec.add_development_dependency 'rspec', '~> 3.0'
@@ -44,4 +53,5 @@ Gem::Specification.new do |spec|
44
53
  # Coveralls gem does not support any newer version than this
45
54
  spec.add_development_dependency 'simplecov', '<= 0.16.1'
46
55
  spec.add_development_dependency 'test-unit', '< 4.0.0'
56
+ spec.add_development_dependency 'yard', '< 1.0'
47
57
  end
data/lib/cuke_modeler.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # The top level namespace used by this gem
2
-
3
2
  module CukeModeler
4
3
  end
5
4
 
@@ -0,0 +1,13 @@
1
+ require_relative 'gherkin_9_adapter'
2
+
3
+
4
+ module CukeModeler
5
+
6
+ # NOT A PART OF THE PUBLIC API
7
+ # An adapter that can convert the output of version 17.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+
10
+ class Gherkin17Adapter < Gherkin9Adapter
11
+
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'gherkin_9_adapter'
2
+
3
+
4
+ module CukeModeler
5
+
6
+ # NOT A PART OF THE PUBLIC API
7
+ # An adapter that can convert the output of version 18.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+ class Gherkin18Adapter < Gherkin9Adapter
10
+
11
+ # Adapts the AST sub-tree that is rooted at the given rule node.
12
+ def adapt_rule(rule_ast)
13
+ adapted_rule = super(rule_ast)
14
+
15
+ clear_child_elements(adapted_rule, [[:rule, :tags]])
16
+
17
+ # Tagging of Rules was added in Gherkin 18
18
+ adapted_rule['tags'] = adapt_tags(rule_ast[:rule])
19
+
20
+ adapted_rule
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,61 @@
1
+ require_relative 'gherkin_18_adapter'
2
+
3
+
4
+ module CukeModeler
5
+
6
+ # NOT A PART OF THE PUBLIC API
7
+ # An adapter that can convert the output of version 19.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+ class Gherkin19Adapter < Gherkin18Adapter
10
+
11
+ # Adapts the AST sub-tree that is rooted at the given step node.
12
+ def adapt_step(step_ast)
13
+ adapted_step = super(step_ast)
14
+
15
+ clear_child_elements(adapted_step, [[:dataTable],
16
+ [:docString]])
17
+
18
+ if step_ast[:docString]
19
+ adapted_step['doc_string'] = adapt_doc_string(step_ast[:docString])
20
+ elsif step_ast[:dataTable]
21
+ adapted_step['table'] = adapt_step_table(step_ast[:dataTable])
22
+ end
23
+
24
+ adapted_step
25
+ end
26
+
27
+ # Adapts the AST sub-tree that is rooted at the given doc string node.
28
+ def adapt_doc_string(doc_string_ast)
29
+ adapted_doc_string = super(doc_string_ast)
30
+
31
+ adapted_doc_string['content_type'] = doc_string_ast[:mediaType]
32
+
33
+ adapted_doc_string
34
+ end
35
+
36
+ # Adapts the AST sub-tree that is rooted at the given example node.
37
+ def adapt_example(example_ast)
38
+ adapted_example = super(example_ast)
39
+
40
+ clear_child_elements(adapted_example, [[:tableHeader],
41
+ [:tableBody]])
42
+
43
+ adapted_example['rows'] << adapt_table_row(example_ast[:tableHeader]) if example_ast[:tableHeader]
44
+
45
+ example_ast[:tableBody].each do |row|
46
+ adapted_example['rows'] << adapt_table_row(row)
47
+ end
48
+
49
+ adapted_example
50
+ end
51
+
52
+
53
+ private
54
+
55
+
56
+ def test_has_examples?(ast_node)
57
+ ast_node[:scenario][:examples].any?
58
+ end
59
+
60
+ end
61
+ end
@@ -6,7 +6,6 @@ module CukeModeler
6
6
  # NOT A PART OF THE PUBLIC API
7
7
  # An adapter that can convert the output of version 9.x of the *cucumber-gherkin* gem into input that is consumable
8
8
  # by this gem.
9
-
10
9
  class Gherkin9Adapter
11
10
 
12
11
  # Adapts the given AST into the shape that this gem expects
@@ -329,6 +328,7 @@ module CukeModeler
329
328
 
330
329
  def clear_child_elements(ast, child_paths)
331
330
  child_paths.each do |traversal_path|
331
+ # Wipe the value if it's there but don't add any keys to the hash if it didn't already have them
332
332
  if ast['cuke_modeler_parsing_data'].dig(*traversal_path)
333
333
  bury(ast['cuke_modeler_parsing_data'], traversal_path, nil)
334
334
  end
@@ -347,11 +347,11 @@ module CukeModeler
347
347
  end
348
348
 
349
349
  def test_node?(ast_node)
350
- ast_node[:scenario]
350
+ !ast_node[:scenario].nil?
351
351
  end
352
352
 
353
353
  def test_has_examples?(ast_node)
354
- ast_node[:scenario][:examples]
354
+ !ast_node[:scenario][:examples].nil?
355
355
  end
356
356
 
357
357
  def test_uses_outline_keyword?(test_ast)
@@ -5,10 +5,24 @@ module CukeModeler
5
5
 
6
6
  # NOT A PART OF THE PUBLIC API
7
7
  # A mix-in module containing methods used by models that contain other models.
8
-
9
8
  module Containing
10
9
 
10
+ include Enumerable
11
+
12
+ # Executes the given code block with this model and every model that is a child of this model. Exact
13
+ # order of model tree traversal is not guaranteed beyond the first model traversed, which will be the
14
+ # model that called this method. If no block is provided, an `Enumerator` is returned instead.
15
+ def each(&block)
16
+ if block
17
+ block.call(self)
18
+ children.each { |child| child.each(&block) }
19
+ else
20
+ to_enum(:each)
21
+ end
22
+ end
23
+
11
24
  # Executes the given code block with every model that is a child of this model.
25
+ # DEPRECATED: use `Enumerable` module methods instead
12
26
  def each_descendant(&block)
13
27
  children.each do |child_model|
14
28
  block.call(child_model)
@@ -17,6 +31,7 @@ module CukeModeler
17
31
  end
18
32
 
19
33
  # Executes the given code block with this model and every model that is a child of this model.
34
+ # DEPRECATED: use `Enumerable` module methods instead
20
35
  def each_model(&block)
21
36
  block.call(self)
22
37
 
@@ -135,6 +150,7 @@ module CukeModeler
135
150
  populate_keyword(rule_object, parsed_rule_data)
136
151
  populate_name(rule_object, parsed_rule_data)
137
152
  populate_description(rule_object, parsed_rule_data)
153
+ populate_tags(rule_object, parsed_rule_data)
138
154
  populate_children(rule_object, parsed_rule_data)
139
155
  end
140
156
 
@@ -2,7 +2,6 @@ module CukeModeler
2
2
 
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that represent an element that has a description.
5
-
6
5
  module Described
7
6
 
8
7
  # The description of the element
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a feature's background.
4
-
5
4
  class Background < Model
6
5
 
7
6
  include Parsing
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a single cell of a row.
4
-
5
4
  class Cell < Model
6
5
 
7
6
  include Sourceable
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a comment in a feature file.
4
-
5
4
  class Comment < Model
6
5
 
7
6
  include Parsing
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a directory in a Cucumber suite.
4
-
5
4
  class Directory < Model
6
5
 
7
6
 
@@ -52,8 +51,8 @@ module CukeModeler
52
51
 
53
52
 
54
53
  def process_directory(directory_path)
55
- directory_data = { 'path' => directory_path,
56
- 'directories' => [],
54
+ directory_data = { 'path' => directory_path,
55
+ 'directories' => [],
57
56
  'feature_files' => [] }
58
57
 
59
58
  entries = Dir.entries(directory_path)
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a step's doc string.
4
-
5
4
  class DocString < Model
6
5
 
7
6
  include Parsing
@@ -4,7 +4,6 @@
4
4
  module CukeModeler
5
5
 
6
6
  # A class modeling an example table of an outline.
7
-
8
7
  class Example < Model
9
8
 
10
9
  include Parsing
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a feature in a Cucumber suite.
4
-
5
4
  class Feature < Model
6
5
 
7
6
  include Parsed
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a feature file in a Cucumber suite.
4
-
5
4
  class FeatureFile < Model
6
5
 
7
6
  include Parsed
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling an element of a Cucumber suite.
4
-
5
4
  class Model
6
5
 
7
6
  include Nested
@@ -25,7 +24,6 @@ module CukeModeler
25
24
 
26
25
  # Returns the model objects that belong to this model.
27
26
  def children
28
- # This should be overridden by a child class
29
27
  []
30
28
  end
31
29
 
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling an individual outline in a Cucumber suite.
4
-
5
4
  class Outline < Model
6
5
 
7
6
  include Parsing
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a single row of a step table or example table.
4
-
5
4
  class Row < Model
6
5
 
7
6
  include Sourceable
@@ -25,6 +24,11 @@ module CukeModeler
25
24
  populate_row(self, parsed_row_data)
26
25
  end
27
26
 
27
+ # Returns the model objects that belong to this model.
28
+ def children
29
+ @cells
30
+ end
31
+
28
32
  # Returns a string representation of this model. For a row model,
29
33
  # this will be Gherkin text that is equivalent to the row being modeled.
30
34
  def to_s
@@ -1,13 +1,13 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a rule in a Cucumber suite.
4
-
5
4
  class Rule < Model
6
5
 
7
6
  include Parsing
8
7
  include Parsed
9
8
  include Named
10
9
  include Described
10
+ include Taggable
11
11
  include Sourceable
12
12
 
13
13
 
@@ -24,6 +24,7 @@ module CukeModeler
24
24
  # Creates a new Rule object and, if *source_text* is provided, populates the
25
25
  # object.
26
26
  def initialize(source_text = nil)
27
+ @tags = []
27
28
  @tests = []
28
29
 
29
30
  super(source_text)
@@ -53,17 +54,21 @@ module CukeModeler
53
54
 
54
55
  # Returns the model objects that belong to this model.
55
56
  def children
56
- models = tests
57
+ models = tests + tags
57
58
  models << background if background
58
59
 
59
60
  models
60
61
  end
61
62
 
63
+ # Building strings just isn't pretty
64
+ # rubocop:disable Metrics/AbcSize
65
+
62
66
  # Returns a string representation of this model. For a rule model,
63
67
  # this will be Gherkin text that is equivalent to the rule being modeled.
64
68
  def to_s
65
69
  text = ''
66
70
 
71
+ text << "#{tag_output_string}\n" unless tags.empty?
67
72
  text << "#{@keyword}:#{name_output_string}"
68
73
  text << "\n#{description_output_string}" unless no_description_to_output?
69
74
  text << "\n\n#{background_output_string}" if background
@@ -71,6 +76,7 @@ module CukeModeler
71
76
 
72
77
  text
73
78
  end
79
+ # rubocop:enable Metrics/AbcSize
74
80
 
75
81
 
76
82
  private
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling an individual scenario of a Cucumber suite.
4
-
5
4
  class Scenario < Model
6
5
 
7
6
  include Parsing
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a single step of a background, scenario, or outline.
4
-
5
4
  class Step < Model
6
5
 
7
6
  include Sourceable
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a step's table.
4
-
5
4
  class Table < Model
6
5
 
7
6
  include Parsing
@@ -1,7 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
3
  # A class modeling a tag.
4
-
5
4
  class Tag < Model
6
5
 
7
6
  include Parsing
@@ -2,7 +2,6 @@ module CukeModeler
2
2
 
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that represent an element that has a name.
5
-
6
5
  module Named
7
6
 
8
7
  # The name of the element
@@ -3,7 +3,6 @@ module CukeModeler
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that are nested inside
5
5
  # of other models.
6
-
7
6
  module Nested
8
7
 
9
8
  # The parent model that contains this model
@@ -2,7 +2,6 @@ module CukeModeler
2
2
 
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that are parsed from source text.
5
-
6
5
  module Parsed
7
6
 
8
7
  # The parsing data for this element that was generated by the parsing engine (i.e. the *gherkin* gem)
@@ -3,22 +3,13 @@
3
3
  require 'gherkin'
4
4
 
5
5
 
6
- # The *cucumber-gherkin* gem loads differently and has different grammar rules across major versions. Parsing
7
- # will be done with an 'adapter' appropriate to the version of the *cucumber-gherkin* gem that has been activated.
8
-
6
+ # The *cucumber-gherkin* has different grammar rules across major versions. Parsing will be done with
7
+ # an 'adapter' appropriate to the version of the *cucumber-gherkin* gem that has been activated.
9
8
  gherkin_version = Gem.loaded_specs['cucumber-gherkin'].version.version
10
9
  gherkin_major_version = gherkin_version.match(/^(\d+)\./)[1].to_i
10
+ supported_gherkin_versions = (9..19)
11
11
 
12
- # Previous versions of the gem did not use the conventional entry point, so I'm leaving this here in case it
13
- # changes again
14
- # rubocop:disable Lint/EmptyWhen
15
- case gherkin_major_version
16
- when 9, 10, 11, 12, 13, 14, 15, 16
17
- # Currently nothing else to load beyond the entry point to the gem
18
- else
19
- raise("Unknown Gherkin version: '#{gherkin_version}'")
20
- end
21
- # rubocop:enable Lint/EmptyWhen
12
+ raise("Unknown Gherkin version: '#{gherkin_version}'") unless supported_gherkin_versions.include?(gherkin_major_version)
22
13
 
23
14
  require "cuke_modeler/adapters/gherkin_#{gherkin_major_version}_adapter"
24
15
 
@@ -26,7 +17,6 @@ require "cuke_modeler/adapters/gherkin_#{gherkin_major_version}_adapter"
26
17
  module CukeModeler
27
18
 
28
19
  # A module providing source text parsing functionality.
29
-
30
20
  module Parsing
31
21
 
32
22
  class << self
@@ -71,7 +61,24 @@ module CukeModeler
71
61
  # inside of it, so I'm leaving this here in case it changes again
72
62
  # rubocop:disable Lint/DuplicateMethods
73
63
  case gherkin_major_version
74
- when 13, 14, 15, 16
64
+ when 19
65
+ # TODO: make these methods private?
66
+ # NOT A PART OF THE PUBLIC API
67
+ # The method to use for parsing Gherkin text
68
+ def parsing_method(source_text, filename)
69
+ messages = Gherkin.from_source(filename,
70
+ source_text,
71
+ { include_gherkin_document: true })
72
+ .to_a.map(&:to_hash)
73
+
74
+ error_message = messages.find { |message| message[:parseError] }
75
+ gherkin_ast_message = messages.find { |message| message[:gherkinDocument] }
76
+
77
+ raise error_message[:parseError][:message] if error_message
78
+
79
+ gherkin_ast_message[:gherkinDocument]
80
+ end
81
+ when 13, 14, 15, 16, 17, 18
75
82
  # TODO: make these methods private?
76
83
  # NOT A PART OF THE PUBLIC API
77
84
  # The method to use for parsing Gherkin text
@@ -3,7 +3,6 @@ module CukeModeler
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that know from which line of
5
5
  # source code they originate.
6
-
7
6
  module Sourceable
8
7
 
9
8
  # The line number where the element began in the source code
@@ -2,7 +2,6 @@ module CukeModeler
2
2
 
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that represent an element that has steps.
5
-
6
5
  module Stepped
7
6
 
8
7
 
@@ -2,7 +2,6 @@ module CukeModeler
2
2
 
3
3
  # NOT A PART OF THE PUBLIC API
4
4
  # A mix-in module containing methods used by models that represent an element that can be tagged.
5
-
6
5
  module Taggable
7
6
 
8
7
  # The models for tags which are directly assigned to the element
@@ -1,4 +1,4 @@
1
1
  module CukeModeler
2
2
  # The gem version
3
- VERSION = '3.5.0'.freeze
3
+ VERSION = '3.10.0'.freeze
4
4
  end
@@ -1,7 +1,8 @@
1
1
  Feature: Rule modeling
2
2
 
3
- Rule models Scenario portion of a feature. They expose several attributes of the rule that they represent, as well as
4
- containing models for any background, scenarios, or outlines that are present in that rule.
3
+ Rule models represent a Rule portion of a feature. They expose several attributes of the rule that they
4
+ represent, as well as containing models for any background, scenarios, outlines, and tags that are present
5
+ in that rule.
5
6
 
6
7
 
7
8
  Background:
@@ -86,6 +87,47 @@ containing models for any background, scenarios, or outlines that are present in
86
87
  Then the model returns models for the following outlines:
87
88
  | Outline 1 |
88
89
 
90
+ @gherkin_min_version_18
91
+ Scenario: Modeling a rules's tags
92
+ Given the following gherkin:
93
+ """
94
+ @feature_tag
95
+ Feature:
96
+
97
+ @rule_tag_1
98
+ @rule_tag_2
99
+ Rule:
100
+ """
101
+ And a feature model based on that gherkin
102
+ """
103
+ @model = CukeModeler::Feature.new(<source_text>)
104
+ """
105
+ And the rule model of that feature model
106
+ """
107
+ @model = @model.rules.first
108
+ """
109
+ When the rules's tags are requested
110
+ """
111
+ @model.tags
112
+ """
113
+ Then the model returns models for the following tags:
114
+ | @rule_tag_1 |
115
+ | @rule_tag_2 |
116
+ When the rule's inherited tags are requested
117
+ """
118
+ @model.applied_tags
119
+ """
120
+ Then the model returns models for the following tags:
121
+ | @feature_tag |
122
+ When all of the rule's tags are requested
123
+ """
124
+ @model.all_tags
125
+ """
126
+ Then the model returns models for the following tags:
127
+ | @feature_tag |
128
+ | @rule_tag_1 |
129
+ | @rule_tag_2 |
130
+
89
131
  Scenario: Modeling a rule's source line
90
132
  Given the following gherkin:
91
133
  """
@@ -4,9 +4,12 @@ Feature: Rule output
4
4
  input for the same kind of model.
5
5
 
6
6
 
7
+ @gherkin_min_version_18
7
8
  Scenario: Outputting a rule model
8
9
  Given the following gherkin:
9
10
  """
11
+ @tag1@tag2
12
+ @tag3
10
13
  Rule: A rule with everything it could have
11
14
  Including a description
12
15
  and then some.
@@ -54,6 +57,7 @@ Feature: Rule output
54
57
  """
55
58
  Then the following text is provided:
56
59
  """
60
+ @tag1 @tag2 @tag3
57
61
  Rule: A rule with everything it could have
58
62
 
59
63
  Including a description
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuke_modeler
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0
4
+ version: 3.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kessler
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-19 00:00:00.000000000 Z
11
+ date: 2021-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber-gherkin
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "<"
18
18
  - !ruby/object:Gem::Version
19
- version: '17.0'
19
+ version: '20.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "<"
25
25
  - !ruby/object:Gem::Version
26
- version: '17.0'
26
+ version: '20.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "<"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: childprocess
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "<"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "<"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: coveralls
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -53,39 +67,39 @@ dependencies:
53
67
  - !ruby/object:Gem::Version
54
68
  version: 1.0.0
55
69
  - !ruby/object:Gem::Dependency
56
- name: cucumber
70
+ name: ffi
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: 4.0.0
62
73
  - - "<"
63
74
  - !ruby/object:Gem::Version
64
- version: 6.0.0
75
+ version: '2.0'
65
76
  type: :development
66
77
  prerelease: false
67
78
  version_requirements: !ruby/object:Gem::Requirement
68
79
  requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- version: 4.0.0
72
80
  - - "<"
73
81
  - !ruby/object:Gem::Version
74
- version: 6.0.0
82
+ version: '2.0'
75
83
  - !ruby/object:Gem::Dependency
76
- name: racatt
84
+ name: cucumber
77
85
  requirement: !ruby/object:Gem::Requirement
78
86
  requirements:
79
- - - "~>"
87
+ - - ">="
80
88
  - !ruby/object:Gem::Version
81
- version: '1.0'
89
+ version: 4.0.0
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: 7.0.0
82
93
  type: :development
83
94
  prerelease: false
84
95
  version_requirements: !ruby/object:Gem::Requirement
85
96
  requirements:
86
- - - "~>"
97
+ - - ">="
87
98
  - !ruby/object:Gem::Version
88
- version: '1.0'
99
+ version: 4.0.0
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: 7.0.0
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: rainbow
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -170,13 +184,27 @@ dependencies:
170
184
  - - "<"
171
185
  - !ruby/object:Gem::Version
172
186
  version: 4.0.0
173
- description: "This gem facilitates modeling a test suite that is written in Gherkin
174
- (e.g. Cucumber, \nSpecFlow, Lettuce, etc.). It does this by providing an abstraction
175
- layer on top of the \nAbstract Syntax Tree that the 'cucumber-gherkin' gem generates
176
- when parsing features, \nas well as providing models for feature files and directories
177
- in order to be able to \nhave a fully traversable model tree of a test suite's structure.
178
- These models can then \nbe analyzed or manipulated more easily than the underlying
179
- AST layer."
187
+ - !ruby/object:Gem::Dependency
188
+ name: yard
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "<"
192
+ - !ruby/object:Gem::Version
193
+ version: '1.0'
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "<"
199
+ - !ruby/object:Gem::Version
200
+ version: '1.0'
201
+ description: This gem facilitates modeling a test suite that is written in Gherkin
202
+ (e.g. Cucumber, SpecFlow, Lettuce, etc.). It does this by providing an abstraction
203
+ layer on top of the Abstract Syntax Tree that the 'cucumber-gherkin' gem generates
204
+ when parsing features, as well as providing models for feature files and directories
205
+ in order to be able to have a fully traversable model tree of a test suite's structure.
206
+ These models can then be analyzed or manipulated more easily than the underlying
207
+ AST layer.
180
208
  email:
181
209
  - morrow748@gmail.com
182
210
  executables: []
@@ -195,6 +223,9 @@ files:
195
223
  - lib/cuke_modeler/adapters/gherkin_14_adapter.rb
196
224
  - lib/cuke_modeler/adapters/gherkin_15_adapter.rb
197
225
  - lib/cuke_modeler/adapters/gherkin_16_adapter.rb
226
+ - lib/cuke_modeler/adapters/gherkin_17_adapter.rb
227
+ - lib/cuke_modeler/adapters/gherkin_18_adapter.rb
228
+ - lib/cuke_modeler/adapters/gherkin_19_adapter.rb
198
229
  - lib/cuke_modeler/adapters/gherkin_9_adapter.rb
199
230
  - lib/cuke_modeler/containing.rb
200
231
  - lib/cuke_modeler/described.rb
@@ -259,8 +290,13 @@ files:
259
290
  homepage: https://github.com/enkessler/cuke_modeler
260
291
  licenses:
261
292
  - MIT
262
- metadata: {}
263
- post_install_message:
293
+ metadata:
294
+ bug_tracker_uri: https://github.com/enkessler/cuke_modeler/issues
295
+ changelog_uri: https://github.com/enkessler/cuke_modeler/blob/master/CHANGELOG.md
296
+ documentation_uri: https://www.rubydoc.info/gems/cuke_modeler
297
+ homepage_uri: https://github.com/enkessler/cuke_modeler
298
+ source_code_uri: https://github.com/enkessler/cuke_modeler
299
+ post_install_message:
264
300
  rdoc_options: []
265
301
  require_paths:
266
302
  - lib
@@ -271,16 +307,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
271
307
  version: '2.3'
272
308
  - - "<"
273
309
  - !ruby/object:Gem::Version
274
- version: '3.0'
310
+ version: '4.0'
275
311
  required_rubygems_version: !ruby/object:Gem::Requirement
276
312
  requirements:
277
313
  - - ">="
278
314
  - !ruby/object:Gem::Version
279
315
  version: '0'
280
316
  requirements: []
281
- rubyforge_project:
282
- rubygems_version: 2.7.6
283
- signing_key:
317
+ rubygems_version: 3.2.3
318
+ signing_key:
284
319
  specification_version: 4
285
320
  summary: A gem providing functionality to model Gherkin based test suites.
286
321
  test_files: []