cuke_modeler 3.2.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -3
  3. data/LICENSE.txt +1 -1
  4. data/README.md +7 -7
  5. data/cuke_modeler.gemspec +35 -16
  6. data/lib/cuke_modeler.rb +1 -2
  7. data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +2 -1
  8. data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +2 -1
  9. data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +2 -1
  10. data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +2 -1
  11. data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +2 -1
  12. data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +13 -0
  13. data/lib/cuke_modeler/adapters/gherkin_16_adapter.rb +13 -0
  14. data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +13 -0
  15. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +261 -243
  16. data/lib/cuke_modeler/containing.rb +47 -90
  17. data/lib/cuke_modeler/described.rb +40 -2
  18. data/lib/cuke_modeler/models/background.rb +11 -12
  19. data/lib/cuke_modeler/models/cell.rb +13 -8
  20. data/lib/cuke_modeler/models/comment.rb +5 -6
  21. data/lib/cuke_modeler/models/directory.rb +13 -18
  22. data/lib/cuke_modeler/models/doc_string.rb +10 -8
  23. data/lib/cuke_modeler/models/example.rb +63 -46
  24. data/lib/cuke_modeler/models/feature.rb +23 -17
  25. data/lib/cuke_modeler/models/feature_file.rb +5 -8
  26. data/lib/cuke_modeler/models/model.rb +2 -3
  27. data/lib/cuke_modeler/models/outline.rb +19 -15
  28. data/lib/cuke_modeler/models/row.rb +15 -8
  29. data/lib/cuke_modeler/models/rule.rb +11 -10
  30. data/lib/cuke_modeler/models/scenario.rb +17 -13
  31. data/lib/cuke_modeler/models/step.rb +40 -19
  32. data/lib/cuke_modeler/models/table.rb +9 -7
  33. data/lib/cuke_modeler/models/tag.rb +9 -6
  34. data/lib/cuke_modeler/named.rb +5 -2
  35. data/lib/cuke_modeler/nested.rb +22 -19
  36. data/lib/cuke_modeler/parsed.rb +8 -1
  37. data/lib/cuke_modeler/parsing.rb +38 -29
  38. data/lib/cuke_modeler/sourceable.rb +8 -1
  39. data/lib/cuke_modeler/stepped.rb +8 -1
  40. data/lib/cuke_modeler/taggable.rb +9 -2
  41. data/lib/cuke_modeler/version.rb +1 -1
  42. metadata +91 -36
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b152c6307169c73e75c9e2b4798d29cab2c7b8ad7ed086c12a854739940d2eb
4
- data.tar.gz: a50e43b9e28d514d22c0a756be7197e9a5395cdf38fcde50d34e8b1c0c41df53
3
+ metadata.gz: abf3eb894f4814405982ec3e2e664b9b6b0ede9b4c3f41ac99148680e251fdf0
4
+ data.tar.gz: 31e87cc947478d94ad6e5316315698b2af7a7280ecc062a670f9c70e399038fe
5
5
  SHA512:
6
- metadata.gz: 627d1c76575e4c2ed4b97ac2ee2db83c920997bc1296bdf6ecfc530ba92250d585c011fa9e315b2c52c28cd9c1f219da7cf1e79fe44e23d0ba868db3de48ffda
7
- data.tar.gz: 3f1c554b800ed1a194d800d13ce9b39e5e4dd5655780e6e3ef007e7e2480d3139d5d8feec128d9db470cf3b8d0a996a5116af0a0770e80e20ee1899cbf661b3a
6
+ metadata.gz: cc973033937d9bad34a2a47da77901850e6ce2e9de6cf875a0d51f6fe634e64f48cf42d4a4ca154e308982dff0e945bd002df98a48e725c8a5705e2f78720522
7
+ data.tar.gz: 73b177f6e22947a5301fbfae5a90fde84394e50adf5d7790f783d8fdea7f2b46c2b7025c0a483f80ce31f3707970051d8b7b3717299fd60adbbf6ab736e4cac6
data/CHANGELOG.md CHANGED
@@ -6,7 +6,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- Nothing yet...
9
+ Noting yet...
10
+
11
+
12
+ ## [3.7.0] - 2021-02-18
13
+
14
+ ### Added
15
+ - Support added for more versions of the `cucumber-gherkin` gem
16
+ - 17.x
17
+
18
+
19
+ ## [3.6.0] - 2021-01-05
20
+
21
+ ### Added
22
+ - Ruby 3.x is now supported
23
+ - All models are now `Enumerable`. However, some methods such as `Enumerable#max` and `Enumerable#sort` do not work
24
+ because models do not meaningfully compare to each other.
25
+
26
+ ### Deprecated
27
+ - `Model#each_descendant` and `Model#each_model` will be removed on the next major release. `Model#each` and methods in
28
+ the `Enumerable` module now provide this kind of functionality.
29
+
30
+ ### Fixed
31
+ - `Row#children` now returns the row's `Cell` models instead of returning an empty array
32
+
33
+
34
+ ## [3.5.0] - 2020-12-19
35
+
36
+ ### Added
37
+ - Support added for more versions of the `cucumber-gherkin` gem
38
+ - 16.x
39
+
40
+ ## [3.4.0] - 2020-09-02
41
+
42
+ ### Added
43
+ - `Feature#has_background?` and `Rule#has_background?` now both have a more conventional name via the alias `#background?`
44
+
45
+ ## [3.3.0] - 2020-08-15
46
+
47
+ ### Added
48
+ - Support added for more versions of the `cucumber-gherkin` gem
49
+ - 15.x
10
50
 
11
51
  ## [3.2.0] - 2020-07-27
12
52
 
@@ -312,7 +352,7 @@ Nothing yet...
312
352
 
313
353
  ### Fixed
314
354
 
315
- - Fixed a bug that was causing object comparison using #== to not
355
+ - Fixed a bug that was causing object comparison using `#==` to not
316
356
  work when comparing some models to other types of objects.
317
357
 
318
358
 
@@ -323,7 +363,12 @@ Nothing yet...
323
363
  - Initial release
324
364
 
325
365
 
326
- [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.2.0...HEAD
366
+ [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.7.0...HEAD
367
+ [3.7.0]: https://github.com/enkessler/cuke_modeler/compare/v3.6.0...v3.7.0
368
+ [3.6.0]: https://github.com/enkessler/cuke_modeler/compare/v3.5.0...v3.6.0
369
+ [3.5.0]: https://github.com/enkessler/cuke_modeler/compare/v3.4.0...v3.5.0
370
+ [3.4.0]: https://github.com/enkessler/cuke_modeler/compare/v3.3.0...v3.4.0
371
+ [3.3.0]: https://github.com/enkessler/cuke_modeler/compare/v3.2.0...v3.3.0
327
372
  [3.2.0]: https://github.com/enkessler/cuke_modeler/compare/v3.1.0...v3.2.0
328
373
  [3.1.0]: https://github.com/enkessler/cuke_modeler/compare/v3.0.0...v3.1.0
329
374
  [3.0.0]: https://github.com/enkessler/cuke_modeler/compare/v2.1.0...v3.0.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
 
@@ -84,12 +84,12 @@ 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
 
91
91
  The modeling functionality provided by this gem will work with any dialect that
92
- is supported by the **gherkin** gem. For modeling at the feature level or higher,
92
+ is supported by the **cucumber-gherkin** gem. For modeling at the feature level or higher,
93
93
  no additional effort is needed because the `# language` header at the top of a
94
94
  feature already indicates that a non-default dialect is being used.
95
95
 
data/cuke_modeler.gemspec CHANGED
@@ -1,17 +1,29 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'cuke_modeler/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "cuke_modeler"
6
+ spec.name = 'cuke_modeler'
8
7
  spec.version = CukeModeler::VERSION
9
- spec.authors = ["Eric Kessler"]
10
- spec.email = ["morrow748@gmail.com"]
11
- spec.summary = %q{A gem providing functionality to model Gherkin based test suites.}
12
- spec.description = %q{This gem facilitates modeling a test suite that is written in Gherkin (e.g. Cucumber, SpecFlow, Lettuce, etc.). It does this by providing an abstraction layer on top of the Abstract Syntax Tree that the 'cucumber-gherkin' gem generates when parsing features, as well as providing models for feature files and directories in order to be able to have a fully traversable model tree of a test suite's structure. These models can then be analyzed or manipulated more easily than the underlying AST layer.}
8
+ spec.authors = ['Eric Kessler']
9
+ spec.email = ['morrow748@gmail.com']
10
+ spec.summary = 'A gem providing functionality to model Gherkin based test suites.'
11
+ spec.description = ['This gem facilitates modeling a test suite that is written in Gherkin (e.g. Cucumber, ',
12
+ 'SpecFlow, Lettuce, etc.). It does this by providing an abstraction layer on top of the ',
13
+ "Abstract Syntax Tree that the 'cucumber-gherkin' gem generates when parsing features, ",
14
+ 'as well as providing models for feature files and directories in order to be able to ',
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
13
17
  spec.homepage = 'https://github.com/enkessler/cuke_modeler'
14
- spec.license = "MIT"
18
+ spec.license = 'MIT'
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
+ }
15
27
 
16
28
  # Specify which files should be added to the gem when it is released.
17
29
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -20,19 +32,26 @@ Gem::Specification.new do |spec|
20
32
  source_controlled_files.keep_if { |file| file =~ %r{^(lib|testing/cucumber/features)} }
21
33
  source_controlled_files + ['README.md', 'LICENSE.txt', 'CHANGELOG.md', 'cuke_modeler.gemspec']
22
34
  end
23
- spec.require_paths = ["lib"]
35
+ spec.require_paths = ['lib']
24
36
 
25
- spec.required_ruby_version = '>= 2.3', '< 3.0'
37
+ spec.required_ruby_version = '>= 2.3', '< 4.0'
26
38
 
27
- spec.add_runtime_dependency 'cucumber-gherkin', '< 15.0'
39
+ spec.add_runtime_dependency 'cucumber-gherkin', '< 18.0'
28
40
 
29
41
  spec.add_development_dependency 'bundler', '< 3.0'
30
- spec.add_development_dependency "rake", '< 13.0.0'
31
- spec.add_development_dependency 'cucumber', '< 5.0.0'
32
- spec.add_development_dependency 'rspec', '~> 3.0'
33
- spec.add_development_dependency 'simplecov', '<= 0.16.1'
34
- spec.add_development_dependency 'racatt', '~> 1.0'
42
+ spec.add_development_dependency 'childprocess', '< 5.0'
35
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
45
+ # Cucumber 4.x is the earliest version to use cucumber-gherkin
46
+ spec.add_development_dependency 'cucumber', '>= 4.0.0', '< 6.0.0'
36
47
  spec.add_development_dependency 'rainbow', '< 4.0.0'
48
+ spec.add_development_dependency 'rake', '< 14.0.0'
49
+ spec.add_development_dependency 'rspec', '~> 3.0'
50
+ # RuboCop drops Ruby 2.3 support after this version and we need to maintain Ruby 2.3 compatibility when writing code
51
+ # for this gem
52
+ spec.add_development_dependency 'rubocop', '< 0.82.0'
53
+ # Coveralls gem does not support any newer version than this
54
+ spec.add_development_dependency 'simplecov', '<= 0.16.1'
37
55
  spec.add_development_dependency 'test-unit', '< 4.0.0'
56
+ spec.add_development_dependency 'yard', '< 1.0'
38
57
  end
data/lib/cuke_modeler.rb CHANGED
@@ -1,10 +1,9 @@
1
1
  # The top level namespace used by this gem
2
-
3
2
  module CukeModeler
4
3
  end
5
4
 
6
5
 
7
- require "cuke_modeler/version"
6
+ require 'cuke_modeler/version'
8
7
 
9
8
  require 'cuke_modeler/parsing'
10
9
  require 'cuke_modeler/containing'
@@ -4,7 +4,8 @@ require_relative 'gherkin_9_adapter'
4
4
  module CukeModeler
5
5
 
6
6
  # NOT A PART OF THE PUBLIC API
7
- # An adapter that can convert the output of version 10.x of the *cucumber-gherkin* gem into input that is consumable by this gem.
7
+ # An adapter that can convert the output of version 10.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
8
9
 
9
10
  class Gherkin10Adapter < Gherkin9Adapter
10
11
 
@@ -4,7 +4,8 @@ require_relative 'gherkin_9_adapter'
4
4
  module CukeModeler
5
5
 
6
6
  # NOT A PART OF THE PUBLIC API
7
- # An adapter that can convert the output of version 11.x of the *cucumber-gherkin* gem into input that is consumable by this gem.
7
+ # An adapter that can convert the output of version 11.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
8
9
 
9
10
  class Gherkin11Adapter < Gherkin9Adapter
10
11
 
@@ -4,7 +4,8 @@ require_relative 'gherkin_9_adapter'
4
4
  module CukeModeler
5
5
 
6
6
  # NOT A PART OF THE PUBLIC API
7
- # An adapter that can convert the output of version 12.x of the *cucumber-gherkin* gem into input that is consumable by this gem.
7
+ # An adapter that can convert the output of version 12.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
8
9
 
9
10
  class Gherkin12Adapter < Gherkin9Adapter
10
11
 
@@ -4,7 +4,8 @@ require_relative 'gherkin_9_adapter'
4
4
  module CukeModeler
5
5
 
6
6
  # NOT A PART OF THE PUBLIC API
7
- # An adapter that can convert the output of version 13.x of the *cucumber-gherkin* gem into input that is consumable by this gem.
7
+ # An adapter that can convert the output of version 13.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
8
9
 
9
10
  class Gherkin13Adapter < Gherkin9Adapter
10
11
 
@@ -4,7 +4,8 @@ require_relative 'gherkin_9_adapter'
4
4
  module CukeModeler
5
5
 
6
6
  # NOT A PART OF THE PUBLIC API
7
- # An adapter that can convert the output of version 14.x of the *cucumber-gherkin* gem into input that is consumable by this gem.
7
+ # An adapter that can convert the output of version 14.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
8
9
 
9
10
  class Gherkin14Adapter < Gherkin9Adapter
10
11
 
@@ -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 15.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+
10
+ class Gherkin15Adapter < Gherkin9Adapter
11
+
12
+ end
13
+ end
@@ -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 16.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+
10
+ class Gherkin16Adapter < Gherkin9Adapter
11
+
12
+ end
13
+ end
@@ -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
@@ -1,345 +1,363 @@
1
+ # Some things just aren't going to get better due to the inherent complexity of the AST
2
+ # rubocop:disable Metrics/ClassLength, Metrics/AbcSize, Metrics/MethodLength
3
+
1
4
  module CukeModeler
2
5
 
3
6
  # NOT A PART OF THE PUBLIC API
4
- # An adapter that can convert the output of version 9.x of the *cucumber-gherkin* gem into input that is consumable by this gem.
5
-
7
+ # An adapter that can convert the output of version 9.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
6
9
  class Gherkin9Adapter
7
10
 
8
11
  # Adapts the given AST into the shape that this gem expects
9
- def adapt(parsed_ast)
10
- # Saving off the original data
11
- parsed_ast['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_ast))
12
+ def adapt(ast)
13
+ adapted_ast = {}
12
14
 
13
- # Removing parsed data for child elements in order to avoid duplicating data
14
- parsed_ast['cuke_modeler_parsing_data'][:feature] = nil if parsed_ast['cuke_modeler_parsing_data'][:feature]
15
- parsed_ast['cuke_modeler_parsing_data'][:comments] = nil if parsed_ast['cuke_modeler_parsing_data'][:comments]
16
-
17
- parsed_ast['comments'] = []
18
- if parsed_ast[:comments]
19
- parsed_ast[:comments].each do |comment|
20
- adapt_comment!(comment)
21
- end
22
- parsed_ast['comments'].concat(parsed_ast.delete(:comments))
23
- end
15
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
16
+ save_original_data(adapted_ast, ast)
17
+ clear_child_elements(adapted_ast, [[:feature],
18
+ [:comments]])
24
19
 
25
- adapt_feature!(parsed_ast[:feature]) if parsed_ast[:feature]
26
- parsed_ast['feature'] = parsed_ast.delete(:feature)
20
+ adapted_ast['comments'] = adapt_comments(ast)
21
+ adapted_ast['feature'] = adapt_feature(ast[:feature])
27
22
 
28
- parsed_ast
23
+ adapted_ast
29
24
  end
30
25
 
31
26
  # Adapts the AST sub-tree that is rooted at the given feature node.
32
- def adapt_feature!(parsed_feature)
33
- # Saving off the original data
34
- parsed_feature['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_feature))
27
+ def adapt_feature(feature_ast)
28
+ return nil unless feature_ast
35
29
 
36
- # Removing parsed data for child elements in order to avoid duplicating data
37
- parsed_feature['cuke_modeler_parsing_data'][:tags] = nil if parsed_feature['cuke_modeler_parsing_data'][:tags]
38
- parsed_feature['cuke_modeler_parsing_data'][:children] = nil if parsed_feature['cuke_modeler_parsing_data'][:children]
30
+ adapted_feature = {}
39
31
 
40
- parsed_feature['keyword'] = parsed_feature.delete(:keyword)
41
- parsed_feature['name'] = parsed_feature.delete(:name)
42
- parsed_feature['description'] = parsed_feature.delete(:description) || ''
43
- parsed_feature['line'] = parsed_feature.delete(:location)[:line]
32
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
33
+ save_original_data(adapted_feature, feature_ast)
34
+ clear_child_elements(adapted_feature, [[:tags],
35
+ [:children]])
44
36
 
45
- parsed_feature['elements'] = []
46
- if parsed_feature[:children]
47
- adapt_child_elements!(parsed_feature[:children])
48
- parsed_feature['elements'].concat(parsed_feature.delete(:children))
49
- end
37
+ adapted_feature['keyword'] = feature_ast[:keyword]
38
+ adapted_feature['name'] = feature_ast[:name]
39
+ adapted_feature['description'] = feature_ast[:description] || ''
40
+ adapted_feature['line'] = feature_ast[:location][:line]
50
41
 
51
- parsed_feature['tags'] = []
52
- if parsed_feature[:tags]
53
- parsed_feature[:tags].each do |tag|
54
- adapt_tag!(tag)
55
- end
56
- parsed_feature['tags'].concat(parsed_feature.delete(:tags))
57
- end
42
+ adapted_feature['elements'] = adapt_child_elements(feature_ast)
43
+ adapted_feature['tags'] = adapt_tags(feature_ast)
44
+
45
+ adapted_feature
58
46
  end
59
47
 
60
48
  # Adapts the AST sub-tree that is rooted at the given background node.
61
- def adapt_background!(parsed_background)
62
- # Saving off the original data
63
- parsed_background['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_background))
49
+ def adapt_background(background_ast)
50
+ adapted_background = {}
64
51
 
65
- # Removing parsed data for child elements in order to avoid duplicating data
66
- parsed_background['cuke_modeler_parsing_data'][:background][:steps] = nil if parsed_background['cuke_modeler_parsing_data'][:background][:steps]
52
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
53
+ save_original_data(adapted_background, background_ast)
54
+ clear_child_elements(adapted_background, [[:background, :steps]])
67
55
 
68
- parsed_background['type'] = 'Background'
69
- parsed_background['keyword'] = parsed_background[:background].delete(:keyword)
70
- parsed_background['name'] = parsed_background[:background].delete(:name)
71
- parsed_background['description'] = parsed_background[:background].delete(:description) || ''
72
- parsed_background['line'] = parsed_background[:background].delete(:location)[:line]
56
+ adapted_background['type'] = 'Background'
57
+ adapted_background['keyword'] = background_ast[:background][:keyword]
58
+ adapted_background['name'] = background_ast[:background][:name]
59
+ adapted_background['description'] = background_ast[:background][:description] || ''
60
+ adapted_background['line'] = background_ast[:background][:location][:line]
73
61
 
74
- parsed_background['steps'] = []
75
- if parsed_background[:background][:steps]
76
- parsed_background[:background][:steps].each do |step|
77
- adapt_step!(step)
78
- end
79
- parsed_background['steps'].concat(parsed_background[:background].delete(:steps))
80
- end
62
+ adapted_background['steps'] = adapt_steps(background_ast[:background])
63
+
64
+ adapted_background
81
65
  end
82
66
 
83
67
  # Adapts the AST sub-tree that is rooted at the given rule node.
84
- def adapt_rule!(parsed_rule)
85
- # Saving off the original data
86
- parsed_rule['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_rule))
68
+ def adapt_rule(rule_ast)
69
+ adapted_rule = {}
87
70
 
88
- # Removing parsed data for child elements in order to avoid duplicating data
89
- parsed_rule['cuke_modeler_parsing_data'][:rule][:children] = nil if parsed_rule['cuke_modeler_parsing_data'][:rule][:children]
71
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
72
+ save_original_data(adapted_rule, rule_ast)
73
+ clear_child_elements(adapted_rule, [[:rule, :children]])
90
74
 
91
- parsed_rule['type'] = 'Rule'
92
- parsed_rule['keyword'] = parsed_rule[:rule].delete(:keyword)
93
- parsed_rule['name'] = parsed_rule[:rule].delete(:name)
94
- parsed_rule['description'] = parsed_rule[:rule].delete(:description) || ''
95
- parsed_rule['line'] = parsed_rule[:rule].delete(:location)[:line]
75
+ adapted_rule['type'] = 'Rule'
76
+ adapted_rule['keyword'] = rule_ast[:rule][:keyword]
77
+ adapted_rule['name'] = rule_ast[:rule][:name]
78
+ adapted_rule['description'] = rule_ast[:rule][:description] || ''
79
+ adapted_rule['line'] = rule_ast[:rule][:location][:line]
96
80
 
97
- parsed_rule['elements'] = []
98
- if parsed_rule[:rule][:children]
99
- adapt_child_elements!(parsed_rule[:rule][:children])
100
- parsed_rule['elements'].concat(parsed_rule[:rule].delete(:children))
101
- end
81
+ adapted_rule['elements'] = adapt_child_elements(rule_ast[:rule])
82
+
83
+ adapted_rule
102
84
  end
103
85
 
104
86
  # Adapts the AST sub-tree that is rooted at the given scenario node.
105
- def adapt_scenario!(parsed_test)
106
- # Removing parsed data for child elements in order to avoid duplicating data
107
- parsed_test['cuke_modeler_parsing_data'][:scenario][:tags] = nil if parsed_test['cuke_modeler_parsing_data'][:scenario][:tags]
108
- parsed_test['cuke_modeler_parsing_data'][:scenario][:steps] = nil if parsed_test['cuke_modeler_parsing_data'][:scenario][:steps]
109
-
110
- parsed_test['type'] = 'Scenario'
111
- parsed_test['keyword'] = parsed_test[:scenario].delete(:keyword)
112
- parsed_test['name'] = parsed_test[:scenario].delete(:name)
113
- parsed_test['description'] = parsed_test[:scenario].delete(:description) || ''
114
- parsed_test['line'] = parsed_test[:scenario].delete(:location)[:line]
115
-
116
- parsed_test['tags'] = []
117
- if parsed_test[:scenario][:tags]
118
- parsed_test[:scenario][:tags].each do |tag|
119
- adapt_tag!(tag)
120
- end
121
- parsed_test['tags'].concat(parsed_test[:scenario].delete(:tags))
122
- end
87
+ def adapt_scenario(test_ast)
88
+ adapted_scenario = {}
123
89
 
124
- parsed_test['steps'] = []
125
- if parsed_test[:scenario][:steps]
126
- parsed_test[:scenario][:steps].each do |step|
127
- adapt_step!(step)
128
- end
129
- parsed_test['steps'].concat(parsed_test[:scenario].delete(:steps))
130
- end
131
- end
90
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
91
+ save_original_data(adapted_scenario, test_ast)
92
+ clear_child_elements(adapted_scenario, [[:scenario, :tags],
93
+ [:scenario, :steps]])
132
94
 
133
- # Adapts the AST sub-tree that is rooted at the given outline node.
134
- def adapt_outline!(parsed_test)
135
- # Removing parsed data for child elements in order to avoid duplicating data
136
- parsed_test['cuke_modeler_parsing_data'][:scenario][:tags] = nil if parsed_test['cuke_modeler_parsing_data'][:scenario][:tags]
137
- parsed_test['cuke_modeler_parsing_data'][:scenario][:steps] = nil if parsed_test['cuke_modeler_parsing_data'][:scenario][:steps]
138
- parsed_test['cuke_modeler_parsing_data'][:scenario][:examples] = nil if parsed_test['cuke_modeler_parsing_data'][:scenario][:examples]
139
-
140
- parsed_test['type'] = 'ScenarioOutline'
141
- parsed_test['keyword'] = parsed_test[:scenario].delete(:keyword)
142
- parsed_test['name'] = parsed_test[:scenario].delete(:name)
143
- parsed_test['description'] = parsed_test[:scenario].delete(:description) || ''
144
- parsed_test['line'] = parsed_test[:scenario].delete(:location)[:line]
145
-
146
- parsed_test['tags'] = []
147
- if parsed_test[:scenario][:tags]
148
- parsed_test[:scenario][:tags].each do |tag|
149
- adapt_tag!(tag)
150
- end
151
- parsed_test['tags'].concat(parsed_test[:scenario].delete(:tags))
152
- end
95
+ adapted_scenario['type'] = 'Scenario'
96
+ adapted_scenario['keyword'] = test_ast[:scenario][:keyword]
97
+ adapted_scenario['name'] = test_ast[:scenario][:name]
98
+ adapted_scenario['description'] = test_ast[:scenario][:description] || ''
99
+ adapted_scenario['line'] = test_ast[:scenario][:location][:line]
153
100
 
154
- parsed_test['steps'] = []
155
- if parsed_test[:scenario][:steps]
156
- parsed_test[:scenario][:steps].each do |step|
157
- adapt_step!(step)
158
- end
159
- parsed_test['steps'].concat(parsed_test[:scenario].delete(:steps))
160
- end
101
+ adapted_scenario['tags'] = adapt_tags(test_ast[:scenario])
102
+ adapted_scenario['steps'] = adapt_steps(test_ast[:scenario])
161
103
 
162
- parsed_test['examples'] = []
163
- if parsed_test[:scenario][:examples]
164
- parsed_test[:scenario][:examples].each do |step|
165
- adapt_example!(step)
166
- end
167
- parsed_test['examples'].concat(parsed_test[:scenario].delete(:examples))
168
- end
104
+ adapted_scenario
105
+ end
106
+
107
+ # Adapts the AST sub-tree that is rooted at the given outline node.
108
+ def adapt_outline(test_ast)
109
+ adapted_outline = {}
110
+
111
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
112
+ save_original_data(adapted_outline, test_ast)
113
+ clear_child_elements(adapted_outline, [[:scenario, :tags],
114
+ [:scenario, :steps],
115
+ [:scenario, :examples]])
116
+
117
+ adapted_outline['type'] = 'ScenarioOutline'
118
+ adapted_outline['keyword'] = test_ast[:scenario][:keyword]
119
+ adapted_outline['name'] = test_ast[:scenario][:name]
120
+ adapted_outline['description'] = test_ast[:scenario][:description] || ''
121
+ adapted_outline['line'] = test_ast[:scenario][:location][:line]
122
+
123
+ adapted_outline['tags'] = adapt_tags(test_ast[:scenario])
124
+ adapted_outline['steps'] = adapt_steps(test_ast[:scenario])
125
+ adapted_outline['examples'] = adapt_examples(test_ast[:scenario])
126
+
127
+ adapted_outline
169
128
  end
170
129
 
171
130
  # Adapts the AST sub-tree that is rooted at the given example node.
172
- def adapt_example!(parsed_example)
173
- # Saving off the original data
174
- parsed_example['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_example))
131
+ def adapt_example(example_ast)
132
+ adapted_example = {}
175
133
 
176
- # Removing parsed data for child elements in order to avoid duplicating data
177
- parsed_example['cuke_modeler_parsing_data'][:tags] = nil if parsed_example['cuke_modeler_parsing_data'][:tags]
178
- parsed_example['cuke_modeler_parsing_data'][:table_header] = nil if parsed_example['cuke_modeler_parsing_data'][:table_header]
179
- parsed_example['cuke_modeler_parsing_data'][:table_body] = nil if parsed_example['cuke_modeler_parsing_data'][:table_body]
134
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
135
+ save_original_data(adapted_example, example_ast)
136
+ clear_child_elements(adapted_example, [[:tags],
137
+ [:table_header],
138
+ [:table_body]])
180
139
 
181
- parsed_example['keyword'] = parsed_example.delete(:keyword)
182
- parsed_example['name'] = parsed_example.delete(:name)
183
- parsed_example['line'] = parsed_example.delete(:location)[:line]
184
- parsed_example['description'] = parsed_example.delete(:description) || ''
140
+ adapted_example['keyword'] = example_ast[:keyword]
141
+ adapted_example['name'] = example_ast[:name]
142
+ adapted_example['line'] = example_ast[:location][:line]
143
+ adapted_example['description'] = example_ast[:description] || ''
185
144
 
186
- parsed_example['rows'] = []
145
+ adapted_example['rows'] = []
146
+ adapted_example['rows'] << adapt_table_row(example_ast[:table_header]) if example_ast[:table_header]
187
147
 
188
- if parsed_example[:table_header]
189
- adapt_table_row!(parsed_example[:table_header])
190
- parsed_example['rows'] << parsed_example.delete(:table_header)
148
+ example_ast[:table_body]&.each do |row|
149
+ adapted_example['rows'] << adapt_table_row(row)
191
150
  end
192
151
 
193
- if parsed_example[:table_body]
194
- parsed_example[:table_body].each do |row|
195
- adapt_table_row!(row)
196
- end
197
- parsed_example['rows'].concat(parsed_example.delete(:table_body))
198
- end
152
+ adapted_example['tags'] = adapt_tags(example_ast)
199
153
 
200
- parsed_example['tags'] = []
201
- if parsed_example[:tags]
202
- parsed_example[:tags].each do |tag|
203
- adapt_tag!(tag)
204
- end
205
- parsed_example['tags'].concat(parsed_example.delete(:tags))
206
- end
154
+ adapted_example
207
155
  end
208
156
 
209
157
  # Adapts the AST sub-tree that is rooted at the given tag node.
210
- def adapt_tag!(parsed_tag)
158
+ def adapt_tag(tag_ast)
159
+ adapted_tag = {}
160
+
211
161
  # Saving off the original data
212
- parsed_tag['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_tag))
162
+ save_original_data(adapted_tag, tag_ast)
213
163
 
214
- parsed_tag['name'] = parsed_tag.delete(:name)
215
- parsed_tag['line'] = parsed_tag.delete(:location)[:line]
164
+ adapted_tag['name'] = tag_ast[:name]
165
+ adapted_tag['line'] = tag_ast[:location][:line]
166
+
167
+ adapted_tag
216
168
  end
217
169
 
218
170
  # Adapts the AST sub-tree that is rooted at the given comment node.
219
- def adapt_comment!(parsed_comment)
171
+ def adapt_comment(comment_ast)
172
+ adapted_comment = {}
173
+
220
174
  # Saving off the original data
221
- parsed_comment['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_comment))
175
+ save_original_data(adapted_comment, comment_ast)
222
176
 
223
- parsed_comment['text'] = parsed_comment.delete(:text)
224
- parsed_comment['line'] = parsed_comment.delete(:location)[:line]
177
+ adapted_comment['text'] = comment_ast[:text]
178
+ adapted_comment['line'] = comment_ast[:location][:line]
179
+
180
+ adapted_comment
225
181
  end
226
182
 
227
183
  # Adapts the AST sub-tree that is rooted at the given step node.
228
- def adapt_step!(parsed_step)
229
- # Saving off the original data
230
- parsed_step['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_step))
231
-
232
- # Removing parsed data for child elements in order to avoid duplicating data
233
- parsed_step['cuke_modeler_parsing_data'][:data_table] = nil if parsed_step['cuke_modeler_parsing_data'][:data_table]
234
- parsed_step['cuke_modeler_parsing_data'][:doc_string] = nil if parsed_step['cuke_modeler_parsing_data'][:doc_string]
235
-
236
- parsed_step['keyword'] = parsed_step.delete(:keyword)
237
- parsed_step['name'] = parsed_step.delete(:text)
238
- parsed_step['line'] = parsed_step.delete(:location)[:line]
239
-
240
- case
241
- when parsed_step[:doc_string]
242
- adapt_doc_string!(parsed_step[:doc_string])
243
- parsed_step['doc_string'] = parsed_step.delete(:doc_string)
244
- when parsed_step[:data_table]
245
- adapt_step_table!(parsed_step[:data_table])
246
- parsed_step['table'] = parsed_step.delete(:data_table)
247
- else
248
- # Step has no extra argument
184
+ def adapt_step(step_ast)
185
+ adapted_step = {}
186
+
187
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
188
+ save_original_data(adapted_step, step_ast)
189
+ clear_child_elements(adapted_step, [[:data_table],
190
+ [:doc_string]])
191
+
192
+ adapted_step['keyword'] = step_ast[:keyword]
193
+ adapted_step['name'] = step_ast[:text]
194
+ adapted_step['line'] = step_ast[:location][:line]
195
+
196
+ if step_ast[:doc_string]
197
+ adapted_step['doc_string'] = adapt_doc_string(step_ast[:doc_string])
198
+ elsif step_ast[:data_table]
199
+ adapted_step['table'] = adapt_step_table(step_ast[:data_table])
249
200
  end
201
+
202
+ adapted_step
250
203
  end
251
204
 
252
205
  # Adapts the AST sub-tree that is rooted at the given doc string node.
253
- def adapt_doc_string!(parsed_doc_string)
206
+ def adapt_doc_string(doc_string_ast)
207
+ adapted_doc_string = {}
208
+
254
209
  # Saving off the original data
255
- parsed_doc_string['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_doc_string))
210
+ save_original_data(adapted_doc_string, doc_string_ast)
211
+
212
+ adapted_doc_string['value'] = doc_string_ast[:content]
213
+ adapted_doc_string['content_type'] = doc_string_ast[:media_type]
214
+ adapted_doc_string['line'] = doc_string_ast[:location][:line]
256
215
 
257
- parsed_doc_string['value'] = parsed_doc_string.delete(:content)
258
- parsed_doc_string['content_type'] = parsed_doc_string.delete(:media_type)
259
- parsed_doc_string['line'] = parsed_doc_string.delete(:location)[:line]
216
+ adapted_doc_string
260
217
  end
261
218
 
262
219
  # Adapts the AST sub-tree that is rooted at the given table node.
263
- def adapt_step_table!(parsed_step_table)
264
- # Saving off the original data
265
- parsed_step_table['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_step_table))
220
+ def adapt_step_table(step_table_ast)
221
+ adapted_step_table = {}
266
222
 
267
- # Removing parsed data for child elements in order to avoid duplicating data
268
- parsed_step_table['cuke_modeler_parsing_data'][:rows] = nil
223
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
224
+ save_original_data(adapted_step_table, step_table_ast)
225
+ clear_child_elements(adapted_step_table, [[:rows]])
269
226
 
270
- parsed_step_table['rows'] = []
271
- parsed_step_table[:rows].each do |row|
272
- adapt_table_row!(row)
227
+ adapted_step_table['rows'] = []
228
+ step_table_ast[:rows].each do |row|
229
+ adapted_step_table['rows'] << adapt_table_row(row)
273
230
  end
274
- parsed_step_table['rows'].concat(parsed_step_table.delete(:rows))
275
- parsed_step_table['line'] = parsed_step_table.delete(:location)[:line]
231
+ adapted_step_table['line'] = step_table_ast[:location][:line]
232
+
233
+ adapted_step_table
276
234
  end
277
235
 
278
236
  # Adapts the AST sub-tree that is rooted at the given row node.
279
- def adapt_table_row!(parsed_table_row)
280
- # Saving off the original data
281
- parsed_table_row['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_table_row))
237
+ def adapt_table_row(table_row_ast)
238
+ adapted_table_row = {}
282
239
 
283
- # Removing parsed data for child elements in order to avoid duplicating data which the child elements will themselves include
284
- parsed_table_row['cuke_modeler_parsing_data'][:cells] = nil
240
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
241
+ save_original_data(adapted_table_row, table_row_ast)
242
+ clear_child_elements(adapted_table_row, [[:cells]])
285
243
 
286
- parsed_table_row['line'] = parsed_table_row.delete(:location)[:line]
244
+ adapted_table_row['line'] = table_row_ast[:location][:line]
287
245
 
288
- parsed_table_row['cells'] = []
289
- parsed_table_row[:cells].each do |row|
290
- adapt_table_cell!(row)
246
+ adapted_table_row['cells'] = []
247
+ table_row_ast[:cells].each do |row|
248
+ adapted_table_row['cells'] << adapt_table_cell(row)
291
249
  end
292
- parsed_table_row['cells'].concat(parsed_table_row.delete(:cells))
250
+
251
+ adapted_table_row
293
252
  end
294
253
 
295
254
  # Adapts the AST sub-tree that is rooted at the given cell node.
296
- def adapt_table_cell!(parsed_cell)
255
+ def adapt_table_cell(cell_ast)
256
+ adapted_cell = {}
257
+
297
258
  # Saving off the original data
298
- parsed_cell['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_cell))
259
+ save_original_data(adapted_cell, cell_ast)
299
260
 
300
- parsed_cell['value'] = parsed_cell.delete(:value)
301
- parsed_cell['line'] = parsed_cell.delete(:location)[:line]
261
+ adapted_cell['value'] = cell_ast[:value]
262
+ adapted_cell['line'] = cell_ast[:location][:line]
263
+
264
+ adapted_cell
302
265
  end
303
266
 
304
267
 
305
268
  private
306
269
 
307
270
 
308
- def adapt_child_elements!(parsed_children)
309
- background_child = parsed_children.find { |child| child[:background] }
310
- rule_children = parsed_children.select { |child| child[:rule] }
311
- remaining_children = parsed_children.reject { |child| child[:background] || child[:rule] }
271
+ def adapt_comments(file_ast)
272
+ return [] unless file_ast[:comments]
273
+
274
+ file_ast[:comments].map { |comment| adapt_comment(comment) }
275
+ end
276
+
277
+ def adapt_tags(element_ast)
278
+ return [] unless element_ast[:tags]
279
+
280
+ element_ast[:tags].map { |tag| adapt_tag(tag) }
281
+ end
282
+
283
+ def adapt_steps(element_ast)
284
+ return [] unless element_ast[:steps]
285
+
286
+ element_ast[:steps].map { |step| adapt_step(step) }
287
+ end
288
+
289
+ def adapt_examples(element_ast)
290
+ return [] unless element_ast[:examples]
291
+
292
+ element_ast[:examples].map { |example| adapt_example(example) }
293
+ end
294
+
295
+ def adapt_child_elements(element_ast)
296
+ return [] unless element_ast[:children]
297
+
298
+ adapted_children = []
299
+
300
+ element_ast[:children].each do |child_element|
301
+ adapted_children << if child_element[:background]
302
+ adapt_background(child_element)
303
+ elsif child_element[:rule]
304
+ adapt_rule(child_element)
305
+ else
306
+ adapt_test(child_element)
307
+ end
308
+ end
312
309
 
313
- adapt_background!(background_child) if background_child
314
- adapt_rules!(rule_children)
315
- adapt_tests!(remaining_children)
310
+ adapted_children
316
311
  end
317
312
 
318
- def adapt_rules!(parsed_rules)
319
- parsed_rules.each do |rule|
320
- adapt_rule!(rule)
313
+ def adapt_test(test_ast)
314
+ if (test_node?(test_ast) && test_has_examples?(test_ast)) ||
315
+ (test_node?(test_ast) && test_uses_outline_keyword?(test_ast))
316
+
317
+ adapt_outline(test_ast)
318
+ elsif test_node?(test_ast)
319
+ adapt_scenario(test_ast)
320
+ else
321
+ raise(ArgumentError, "Unknown test type with keys: #{test_ast.keys}")
321
322
  end
322
323
  end
323
324
 
324
- def adapt_tests!(parsed_tests)
325
- parsed_tests.each do |test|
326
- adapt_test!(test)
325
+ def save_original_data(adapted_ast, raw_ast)
326
+ adapted_ast['cuke_modeler_parsing_data'] = Marshal.load(Marshal.dump(raw_ast))
327
+ end
328
+
329
+ def clear_child_elements(ast, child_paths)
330
+ child_paths.each do |traversal_path|
331
+ if ast['cuke_modeler_parsing_data'].dig(*traversal_path)
332
+ bury(ast['cuke_modeler_parsing_data'], traversal_path, nil)
333
+ end
327
334
  end
328
335
  end
329
336
 
330
- def adapt_test!(parsed_test)
331
- # Saving off the original data
332
- parsed_test['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_test))
333
-
334
- case
335
- when (parsed_test[:scenario] && parsed_test[:scenario][:examples]) || (parsed_test[:scenario] && Parsing.dialects[Parsing.dialect]['scenarioOutline'].include?(parsed_test[:scenario][:keyword]))
336
- adapt_outline!(parsed_test)
337
- when parsed_test[:scenario]
338
- adapt_scenario!(parsed_test)
339
- else
340
- raise(ArgumentError, "Unknown test type with keys: #{parsed_test.keys}")
337
+ def bury(hash, traversal_path, value)
338
+ keys = *traversal_path
339
+
340
+ current = hash
341
+ (keys.count - 1).times do |index|
342
+ current = hash[keys[index]]
341
343
  end
344
+
345
+ current[keys.last] = value
346
+ end
347
+
348
+ def test_node?(ast_node)
349
+ ast_node[:scenario]
350
+ end
351
+
352
+ def test_has_examples?(ast_node)
353
+ ast_node[:scenario][:examples]
354
+ end
355
+
356
+ def test_uses_outline_keyword?(test_ast)
357
+ Parsing.dialects[Parsing.dialect]['scenarioOutline'].include?(test_ast[:scenario][:keyword])
342
358
  end
343
359
 
344
360
  end
345
361
  end
362
+
363
+ # rubocop:enable Metrics/ClassLength, Metrics/AbcSize, Metrics/MethodLength