cuke_modeler 3.3.0 → 3.4.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 +7 -1
- data/cuke_modeler.gemspec +23 -14
- data/lib/cuke_modeler.rb +1 -1
- 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 +2 -1
- data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +261 -242
- data/lib/cuke_modeler/containing.rb +31 -89
- data/lib/cuke_modeler/described.rb +40 -1
- data/lib/cuke_modeler/models/background.rb +11 -11
- data/lib/cuke_modeler/models/cell.rb +13 -7
- data/lib/cuke_modeler/models/comment.rb +5 -5
- data/lib/cuke_modeler/models/directory.rb +13 -17
- data/lib/cuke_modeler/models/doc_string.rb +10 -7
- data/lib/cuke_modeler/models/example.rb +63 -45
- data/lib/cuke_modeler/models/feature.rb +23 -16
- data/lib/cuke_modeler/models/feature_file.rb +5 -7
- data/lib/cuke_modeler/models/model.rb +2 -1
- data/lib/cuke_modeler/models/outline.rb +19 -14
- data/lib/cuke_modeler/models/row.rb +10 -7
- data/lib/cuke_modeler/models/rule.rb +11 -9
- data/lib/cuke_modeler/models/scenario.rb +17 -12
- data/lib/cuke_modeler/models/step.rb +40 -18
- data/lib/cuke_modeler/models/table.rb +9 -6
- data/lib/cuke_modeler/models/tag.rb +9 -5
- data/lib/cuke_modeler/named.rb +5 -1
- data/lib/cuke_modeler/nested.rb +22 -18
- data/lib/cuke_modeler/parsed.rb +8 -0
- data/lib/cuke_modeler/parsing.rb +36 -26
- data/lib/cuke_modeler/sourceable.rb +8 -0
- data/lib/cuke_modeler/stepped.rb +8 -0
- data/lib/cuke_modeler/taggable.rb +9 -1
- data/lib/cuke_modeler/version.rb +1 -1
- metadata +53 -33
@@ -18,10 +18,10 @@ module CukeModeler
|
|
18
18
|
def initialize(source_text = nil)
|
19
19
|
super(source_text)
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
return unless source_text
|
22
|
+
|
23
|
+
parsed_tag_data = parse_source(source_text)
|
24
|
+
populate_tag(self, parsed_tag_data)
|
25
25
|
end
|
26
26
|
|
27
27
|
# Returns a string representation of this model. For a tag model,
|
@@ -38,10 +38,14 @@ module CukeModeler
|
|
38
38
|
base_file_string = "\n#{dialect_feature_keyword}: Fake feature to parse"
|
39
39
|
source_text = "# language: #{Parsing.dialect}\n" + source_text + base_file_string
|
40
40
|
|
41
|
-
parsed_file = Parsing
|
41
|
+
parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_tag.feature')
|
42
42
|
|
43
43
|
parsed_file['feature']['tags'].first
|
44
44
|
end
|
45
45
|
|
46
|
+
def populate_name(model, parsed_model_data)
|
47
|
+
model.name = parsed_model_data['name']
|
48
|
+
end
|
49
|
+
|
46
50
|
end
|
47
51
|
end
|
data/lib/cuke_modeler/named.rb
CHANGED
@@ -13,7 +13,11 @@ module CukeModeler
|
|
13
13
|
|
14
14
|
|
15
15
|
def name_output_string
|
16
|
-
|
16
|
+
name.nil? || name.empty? ? '' : " #{name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def populate_name(model, parsed_model_data)
|
20
|
+
model.name = parsed_model_data['name']
|
17
21
|
end
|
18
22
|
|
19
23
|
end
|
data/lib/cuke_modeler/nested.rb
CHANGED
@@ -12,30 +12,34 @@ module CukeModeler
|
|
12
12
|
|
13
13
|
# Returns the ancestor model of this model that matches the given type.
|
14
14
|
def get_ancestor(ancestor_type)
|
15
|
-
|
16
|
-
:feature_file => [FeatureFile],
|
17
|
-
:feature => [Feature],
|
18
|
-
:test => [Scenario, Outline, Background],
|
19
|
-
:background => [Background],
|
20
|
-
:scenario => [Scenario],
|
21
|
-
:outline => [Outline],
|
22
|
-
:step => [Step],
|
23
|
-
:table => [Table],
|
24
|
-
:example => [Example],
|
25
|
-
:row => [Row]
|
26
|
-
}[ancestor_type]
|
15
|
+
target_classes = classes_for_type(ancestor_type)
|
27
16
|
|
28
|
-
raise(ArgumentError, "Unknown ancestor type '#{ancestor_type}'.") if
|
17
|
+
raise(ArgumentError, "Unknown ancestor type '#{ancestor_type}'.") if target_classes.nil?
|
29
18
|
|
19
|
+
ancestor = parent_model
|
20
|
+
ancestor = ancestor.parent_model until target_classes.include?(ancestor.class) || ancestor.nil?
|
30
21
|
|
31
|
-
ancestor
|
22
|
+
ancestor
|
23
|
+
end
|
32
24
|
|
33
|
-
until target_type.include?(ancestor.class) || ancestor.nil?
|
34
|
-
ancestor = ancestor.parent_model
|
35
|
-
end
|
36
25
|
|
26
|
+
private
|
37
27
|
|
38
|
-
|
28
|
+
|
29
|
+
def classes_for_type(type)
|
30
|
+
{
|
31
|
+
directory: [Directory],
|
32
|
+
feature_file: [FeatureFile],
|
33
|
+
feature: [Feature],
|
34
|
+
test: [Scenario, Outline, Background],
|
35
|
+
background: [Background],
|
36
|
+
scenario: [Scenario],
|
37
|
+
outline: [Outline],
|
38
|
+
step: [Step],
|
39
|
+
table: [Table],
|
40
|
+
example: [Example],
|
41
|
+
row: [Row]
|
42
|
+
}[type]
|
39
43
|
end
|
40
44
|
|
41
45
|
end
|
data/lib/cuke_modeler/parsed.rb
CHANGED
@@ -8,5 +8,13 @@ module CukeModeler
|
|
8
8
|
# The parsing data for this element that was generated by the parsing engine (i.e. the *gherkin* gem)
|
9
9
|
attr_accessor :parsing_data
|
10
10
|
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
|
15
|
+
def populate_parsing_data(model, parsed_model_data)
|
16
|
+
model.parsing_data = parsed_model_data['cuke_modeler_parsing_data']
|
17
|
+
end
|
18
|
+
|
11
19
|
end
|
12
20
|
end
|
data/lib/cuke_modeler/parsing.rb
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
# Have to at least load some version of the gem before which version of the gem has been loaded can
|
2
|
-
# be determined and the rest of the needed files can be loaded.
|
3
|
-
|
4
|
-
begin
|
5
|
-
# Gherkin 9.x
|
6
|
-
require 'gherkin'
|
7
|
-
rescue LoadError => e
|
8
|
-
# Add other entry points again if things change again
|
9
|
-
raise e
|
10
|
-
end
|
2
|
+
# be determined and the rest of the needed files can be loaded.
|
3
|
+
require 'gherkin'
|
11
4
|
|
12
5
|
|
13
6
|
# The *cucumber-gherkin* gem loads differently and has different grammar rules across major versions. Parsing
|
@@ -16,12 +9,16 @@ end
|
|
16
9
|
gherkin_version = Gem.loaded_specs['cucumber-gherkin'].version.version
|
17
10
|
gherkin_major_version = gherkin_version.match(/^(\d+)\./)[1].to_i
|
18
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
|
19
15
|
case gherkin_major_version
|
20
16
|
when 9, 10, 11, 12, 13, 14, 15
|
21
17
|
# Currently nothing else to load beyond the entry point to the gem
|
22
18
|
else
|
23
19
|
raise("Unknown Gherkin version: '#{gherkin_version}'")
|
24
20
|
end
|
21
|
+
# rubocop:enable Lint/EmptyWhen
|
25
22
|
|
26
23
|
require "cuke_modeler/adapters/gherkin_#{gherkin_major_version}_adapter"
|
27
24
|
|
@@ -45,18 +42,16 @@ module CukeModeler
|
|
45
42
|
|
46
43
|
# The dialects currently known by the gherkin gem
|
47
44
|
def dialects
|
48
|
-
|
49
|
-
@dialects = Gherkin::DIALECTS
|
50
|
-
end
|
51
|
-
|
52
|
-
@dialects
|
45
|
+
@dialects ||= Gherkin::DIALECTS
|
53
46
|
end
|
54
47
|
|
55
48
|
# Parses the Cucumber feature given in *source_text* and returns a hash representation of
|
56
49
|
# its logical structure. This is a standardized AST that should remain consistent across
|
57
50
|
# different versions of `cucumber-gherkin`
|
58
51
|
def parse_text(source_text, filename = 'cuke_modeler_fake_file.feature')
|
59
|
-
|
52
|
+
unless source_text.is_a?(String)
|
53
|
+
raise(ArgumentError, "Text to parse must be a String but got #{source_text.class}")
|
54
|
+
end
|
60
55
|
|
61
56
|
begin
|
62
57
|
parsed_result = parsing_method(source_text.encode('UTF-8'), filename)
|
@@ -71,13 +66,20 @@ module CukeModeler
|
|
71
66
|
gherkin_version = Gem.loaded_specs['cucumber-gherkin'].version.version
|
72
67
|
gherkin_major_version = gherkin_version.match(/^(\d+)\./)[1].to_i
|
73
68
|
|
69
|
+
# Previous versions of the gem had more variation between their parsing methods and so it was more
|
70
|
+
# understandable to have different methods instead of a single method with lots of conditional statements
|
71
|
+
# inside of it, so I'm leaving this here in case it changes again
|
72
|
+
# rubocop:disable Lint/DuplicateMethods
|
74
73
|
case gherkin_major_version
|
75
74
|
when 13, 14, 15
|
76
|
-
#
|
75
|
+
# TODO: make these methods private?
|
77
76
|
# NOT A PART OF THE PUBLIC API
|
78
77
|
# The method to use for parsing Gherkin text
|
79
78
|
def parsing_method(source_text, filename)
|
80
|
-
messages = Gherkin.from_source(filename,
|
79
|
+
messages = Gherkin.from_source(filename,
|
80
|
+
source_text,
|
81
|
+
{ include_gherkin_document: true })
|
82
|
+
.to_a.map(&:to_hash)
|
81
83
|
|
82
84
|
error_message = messages.find { |message| message[:parse_error] }
|
83
85
|
gherkin_ast_message = messages.find { |message| message[:gherkin_document] }
|
@@ -87,33 +89,39 @@ module CukeModeler
|
|
87
89
|
gherkin_ast_message[:gherkin_document]
|
88
90
|
end
|
89
91
|
when 12
|
90
|
-
#
|
92
|
+
# TODO: make these methods private?
|
91
93
|
# NOT A PART OF THE PUBLIC API
|
92
94
|
# The method to use for parsing Gherkin text
|
93
95
|
def parsing_method(source_text, filename)
|
94
|
-
messages = Gherkin.from_source(filename,
|
96
|
+
messages = Gherkin.from_source(filename,
|
97
|
+
source_text,
|
98
|
+
{ include_gherkin_document: true })
|
99
|
+
.to_a.map(&:to_hash)
|
95
100
|
|
96
101
|
potential_error_message = messages.find { |message| message[:attachment] }
|
97
102
|
gherkin_ast_message = messages.find { |message| message[:gherkin_document] }
|
98
103
|
|
99
|
-
if potential_error_message
|
100
|
-
raise potential_error_message[:attachment][:body]
|
104
|
+
if potential_error_message && potential_error_message[:attachment][:body] =~ /expected.*got/
|
105
|
+
raise potential_error_message[:attachment][:body]
|
101
106
|
end
|
102
107
|
|
103
108
|
gherkin_ast_message[:gherkin_document]
|
104
109
|
end
|
105
110
|
when 9, 10, 11
|
106
|
-
#
|
111
|
+
# TODO: make these methods private?
|
107
112
|
# NOT A PART OF THE PUBLIC API
|
108
113
|
# The method to use for parsing Gherkin text
|
109
114
|
def parsing_method(source_text, filename)
|
110
|
-
messages = Gherkin.from_source(filename,
|
115
|
+
messages = Gherkin.from_source(filename,
|
116
|
+
source_text,
|
117
|
+
{ include_gherkin_document: true })
|
118
|
+
.to_a.map(&:to_hash)
|
111
119
|
|
112
120
|
potential_error_message = messages.find { |message| message[:attachment] }
|
113
121
|
gherkin_ast_message = messages.find { |message| message[:gherkin_document] }
|
114
122
|
|
115
|
-
if potential_error_message
|
116
|
-
raise potential_error_message[:attachment][:text]
|
123
|
+
if potential_error_message && potential_error_message[:attachment][:text] =~ /expected.*got/
|
124
|
+
raise potential_error_message[:attachment][:text]
|
117
125
|
end
|
118
126
|
|
119
127
|
gherkin_ast_message[:gherkin_document]
|
@@ -121,6 +129,7 @@ module CukeModeler
|
|
121
129
|
else
|
122
130
|
raise("Unknown Gherkin version: '#{gherkin_version}'")
|
123
131
|
end
|
132
|
+
# rubocop:enable Lint/DuplicateMethods
|
124
133
|
|
125
134
|
# NOT A PART OF THE PUBLIC API
|
126
135
|
# The adapter to use when converting an AST to a standard internal shape
|
@@ -143,7 +152,8 @@ module CukeModeler
|
|
143
152
|
end
|
144
153
|
|
145
154
|
def dialect_outline_keyword
|
146
|
-
get_word(Parsing.dialects[Parsing.dialect]['scenarioOutline'] ||
|
155
|
+
get_word(Parsing.dialects[Parsing.dialect]['scenarioOutline'] ||
|
156
|
+
Parsing.dialects[Parsing.dialect]['scenario_outline'])
|
147
157
|
end
|
148
158
|
|
149
159
|
def dialect_step_keyword
|
@@ -9,5 +9,13 @@ module CukeModeler
|
|
9
9
|
# The line number where the element began in the source code
|
10
10
|
attr_accessor :source_line
|
11
11
|
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
|
16
|
+
def populate_source_line(model, parsed_model_data)
|
17
|
+
model.source_line = parsed_model_data['line']
|
18
|
+
end
|
19
|
+
|
12
20
|
end
|
13
21
|
end
|
data/lib/cuke_modeler/stepped.rb
CHANGED
@@ -21,5 +21,13 @@ module CukeModeler
|
|
21
21
|
step.to_s.split("\n").collect { |line| " #{line}" }.join("\n")
|
22
22
|
end
|
23
23
|
|
24
|
+
def populate_steps(model, parsed_model_data)
|
25
|
+
return unless parsed_model_data['steps']
|
26
|
+
|
27
|
+
parsed_model_data['steps'].each do |step_data|
|
28
|
+
model.steps << build_child_model(Step, step_data)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
24
32
|
end
|
25
33
|
end
|
@@ -25,7 +25,15 @@ module CukeModeler
|
|
25
25
|
|
26
26
|
|
27
27
|
def tag_output_string
|
28
|
-
tags.
|
28
|
+
tags.map(&:name).join(' ')
|
29
|
+
end
|
30
|
+
|
31
|
+
def populate_tags(model, parsed_model_data)
|
32
|
+
return unless parsed_model_data['tags']
|
33
|
+
|
34
|
+
parsed_model_data['tags'].each do |tag|
|
35
|
+
model.tags << build_child_model(Tag, tag)
|
36
|
+
end
|
29
37
|
end
|
30
38
|
|
31
39
|
end
|
data/lib/cuke_modeler/version.rb
CHANGED
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.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Kessler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cucumber-gherkin
|
@@ -39,103 +39,123 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: coveralls
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "<"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "<"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: cucumber
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.0.0
|
59
62
|
- - "<"
|
60
63
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
64
|
+
version: 6.0.0
|
62
65
|
type: :development
|
63
66
|
prerelease: false
|
64
67
|
version_requirements: !ruby/object:Gem::Requirement
|
65
68
|
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 4.0.0
|
66
72
|
- - "<"
|
67
73
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
74
|
+
version: 6.0.0
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
76
|
+
name: racatt
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
72
78
|
requirements:
|
73
79
|
- - "~>"
|
74
80
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
81
|
+
version: '1.0'
|
76
82
|
type: :development
|
77
83
|
prerelease: false
|
78
84
|
version_requirements: !ruby/object:Gem::Requirement
|
79
85
|
requirements:
|
80
86
|
- - "~>"
|
81
87
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
88
|
+
version: '1.0'
|
83
89
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
90
|
+
name: rainbow
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
86
92
|
requirements:
|
87
|
-
- - "
|
93
|
+
- - "<"
|
88
94
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
95
|
+
version: 4.0.0
|
90
96
|
type: :development
|
91
97
|
prerelease: false
|
92
98
|
version_requirements: !ruby/object:Gem::Requirement
|
93
99
|
requirements:
|
94
|
-
- - "
|
100
|
+
- - "<"
|
95
101
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
102
|
+
version: 4.0.0
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
104
|
+
name: rake
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "<"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 14.0.0
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "<"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 14.0.0
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rspec
|
99
119
|
requirement: !ruby/object:Gem::Requirement
|
100
120
|
requirements:
|
101
121
|
- - "~>"
|
102
122
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
123
|
+
version: '3.0'
|
104
124
|
type: :development
|
105
125
|
prerelease: false
|
106
126
|
version_requirements: !ruby/object:Gem::Requirement
|
107
127
|
requirements:
|
108
128
|
- - "~>"
|
109
129
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
130
|
+
version: '3.0'
|
111
131
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
132
|
+
name: rubocop
|
113
133
|
requirement: !ruby/object:Gem::Requirement
|
114
134
|
requirements:
|
115
135
|
- - "<"
|
116
136
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
137
|
+
version: 0.82.0
|
118
138
|
type: :development
|
119
139
|
prerelease: false
|
120
140
|
version_requirements: !ruby/object:Gem::Requirement
|
121
141
|
requirements:
|
122
142
|
- - "<"
|
123
143
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
144
|
+
version: 0.82.0
|
125
145
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
146
|
+
name: simplecov
|
127
147
|
requirement: !ruby/object:Gem::Requirement
|
128
148
|
requirements:
|
129
|
-
- - "
|
149
|
+
- - "<="
|
130
150
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
151
|
+
version: 0.16.1
|
132
152
|
type: :development
|
133
153
|
prerelease: false
|
134
154
|
version_requirements: !ruby/object:Gem::Requirement
|
135
155
|
requirements:
|
136
|
-
- - "
|
156
|
+
- - "<="
|
137
157
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
158
|
+
version: 0.16.1
|
139
159
|
- !ruby/object:Gem::Dependency
|
140
160
|
name: test-unit
|
141
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,13 +170,13 @@ dependencies:
|
|
150
170
|
- - "<"
|
151
171
|
- !ruby/object:Gem::Version
|
152
172
|
version: 4.0.0
|
153
|
-
description: This gem facilitates modeling a test suite that is written in Gherkin
|
154
|
-
(e.g. Cucumber,
|
155
|
-
layer on top of the
|
156
|
-
when parsing features,
|
157
|
-
in order to be able to
|
158
|
-
These models can then
|
159
|
-
AST layer.
|
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."
|
160
180
|
email:
|
161
181
|
- morrow748@gmail.com
|
162
182
|
executables: []
|