cuke_modeler 3.2.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -3
- data/LICENSE.txt +1 -1
- data/README.md +7 -7
- data/cuke_modeler.gemspec +35 -16
- data/lib/cuke_modeler.rb +1 -2
- data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +2 -1
- data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +2 -1
- data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +2 -1
- data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +2 -1
- data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +2 -1
- data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +13 -0
- data/lib/cuke_modeler/adapters/gherkin_16_adapter.rb +13 -0
- data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +13 -0
- data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +261 -243
- data/lib/cuke_modeler/containing.rb +47 -90
- data/lib/cuke_modeler/described.rb +40 -2
- data/lib/cuke_modeler/models/background.rb +11 -12
- data/lib/cuke_modeler/models/cell.rb +13 -8
- data/lib/cuke_modeler/models/comment.rb +5 -6
- data/lib/cuke_modeler/models/directory.rb +13 -18
- data/lib/cuke_modeler/models/doc_string.rb +10 -8
- data/lib/cuke_modeler/models/example.rb +63 -46
- data/lib/cuke_modeler/models/feature.rb +23 -17
- data/lib/cuke_modeler/models/feature_file.rb +5 -8
- data/lib/cuke_modeler/models/model.rb +2 -3
- data/lib/cuke_modeler/models/outline.rb +19 -15
- data/lib/cuke_modeler/models/row.rb +15 -8
- data/lib/cuke_modeler/models/rule.rb +11 -10
- data/lib/cuke_modeler/models/scenario.rb +17 -13
- data/lib/cuke_modeler/models/step.rb +40 -19
- data/lib/cuke_modeler/models/table.rb +9 -7
- data/lib/cuke_modeler/models/tag.rb +9 -6
- data/lib/cuke_modeler/named.rb +5 -2
- data/lib/cuke_modeler/nested.rb +22 -19
- data/lib/cuke_modeler/parsed.rb +8 -1
- data/lib/cuke_modeler/parsing.rb +38 -29
- data/lib/cuke_modeler/sourceable.rb +8 -1
- data/lib/cuke_modeler/stepped.rb +8 -1
- data/lib/cuke_modeler/taggable.rb +9 -2
- data/lib/cuke_modeler/version.rb +1 -1
- metadata +91 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abf3eb894f4814405982ec3e2e664b9b6b0ede9b4c3f41ac99148680e251fdf0
|
4
|
+
data.tar.gz: 31e87cc947478d94ad6e5316315698b2af7a7280ecc062a670f9c70e399038fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
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.
|
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
data/README.md
CHANGED
@@ -4,15 +4,15 @@ Basic stuff:
|
|
4
4
|
[](https://rubygems.org/gems/cuke_modeler)
|
5
5
|
|
6
6
|
User stuff:
|
7
|
-
[](https://
|
7
|
+
[](https://github.com/enkessler/cuke_modeler/tree/master/testing/cucumber/features)
|
8
8
|
[](https://www.rubydoc.info/gems/cuke_modeler)
|
9
9
|
|
10
10
|
Developer stuff:
|
11
|
-
[](https://travis-ci.org/enkessler/cuke_modeler)
|
12
|
-
[](https://ci.appveyor.com/project/enkessler/cuke-modeler)
|
13
|
-
[](https://coveralls.io/github/enkessler/cuke_modeler)
|
11
|
+
[](https://travis-ci.org/enkessler/cuke_modeler)
|
12
|
+
[](https://ci.appveyor.com/project/enkessler/cuke-modeler)
|
13
|
+
[](https://coveralls.io/github/enkessler/cuke_modeler?branch=master)
|
14
14
|
[](https://codeclimate.com/github/enkessler/cuke_modeler/maintainability)
|
15
|
-
[](https://inch-ci.org/github/enkessler/cuke_modeler)
|
15
|
+
[](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://
|
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
|
-
|
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 =
|
6
|
+
spec.name = 'cuke_modeler'
|
8
7
|
spec.version = CukeModeler::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
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 =
|
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 = [
|
35
|
+
spec.require_paths = ['lib']
|
24
36
|
|
25
|
-
spec.required_ruby_version = '>= 2.3', '<
|
37
|
+
spec.required_ruby_version = '>= 2.3', '< 4.0'
|
26
38
|
|
27
|
-
spec.add_runtime_dependency 'cucumber-gherkin', '<
|
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
|
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
@@ -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
|
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
|
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
|
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
|
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
|
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
|
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(
|
10
|
-
|
11
|
-
parsed_ast['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_ast))
|
12
|
+
def adapt(ast)
|
13
|
+
adapted_ast = {}
|
12
14
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
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
|
-
|
26
|
-
|
20
|
+
adapted_ast['comments'] = adapt_comments(ast)
|
21
|
+
adapted_ast['feature'] = adapt_feature(ast[:feature])
|
27
22
|
|
28
|
-
|
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
|
33
|
-
|
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
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
62
|
-
|
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
|
-
#
|
66
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
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
|
85
|
-
|
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
|
-
#
|
89
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
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
|
106
|
-
|
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
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
-
|
155
|
-
|
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
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
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
|
173
|
-
|
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
|
-
#
|
177
|
-
|
178
|
-
|
179
|
-
|
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
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
-
|
145
|
+
adapted_example['rows'] = []
|
146
|
+
adapted_example['rows'] << adapt_table_row(example_ast[:table_header]) if example_ast[:table_header]
|
187
147
|
|
188
|
-
|
189
|
-
adapt_table_row
|
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
|
-
|
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
|
-
|
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
|
158
|
+
def adapt_tag(tag_ast)
|
159
|
+
adapted_tag = {}
|
160
|
+
|
211
161
|
# Saving off the original data
|
212
|
-
|
162
|
+
save_original_data(adapted_tag, tag_ast)
|
213
163
|
|
214
|
-
|
215
|
-
|
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
|
171
|
+
def adapt_comment(comment_ast)
|
172
|
+
adapted_comment = {}
|
173
|
+
|
220
174
|
# Saving off the original data
|
221
|
-
|
175
|
+
save_original_data(adapted_comment, comment_ast)
|
222
176
|
|
223
|
-
|
224
|
-
|
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
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
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
|
206
|
+
def adapt_doc_string(doc_string_ast)
|
207
|
+
adapted_doc_string = {}
|
208
|
+
|
254
209
|
# Saving off the original data
|
255
|
-
|
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
|
-
|
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
|
264
|
-
|
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
|
-
#
|
268
|
-
|
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
|
-
|
271
|
-
|
272
|
-
adapt_table_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
|
-
|
275
|
-
|
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
|
280
|
-
|
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
|
-
#
|
284
|
-
|
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
|
-
|
244
|
+
adapted_table_row['line'] = table_row_ast[:location][:line]
|
287
245
|
|
288
|
-
|
289
|
-
|
290
|
-
adapt_table_cell
|
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
|
-
|
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
|
255
|
+
def adapt_table_cell(cell_ast)
|
256
|
+
adapted_cell = {}
|
257
|
+
|
297
258
|
# Saving off the original data
|
298
|
-
|
259
|
+
save_original_data(adapted_cell, cell_ast)
|
299
260
|
|
300
|
-
|
301
|
-
|
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
|
309
|
-
|
310
|
-
|
311
|
-
|
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
|
-
|
314
|
-
adapt_rules!(rule_children)
|
315
|
-
adapt_tests!(remaining_children)
|
310
|
+
adapted_children
|
316
311
|
end
|
317
312
|
|
318
|
-
def
|
319
|
-
|
320
|
-
|
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
|
325
|
-
|
326
|
-
|
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
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
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
|