cuke_modeler 3.10.0 → 3.11.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 +11 -1
- data/README.md +1 -2
- data/cuke_modeler.gemspec +3 -4
- data/lib/cuke_modeler/adapters/gherkin_20_adapter.rb +337 -0
- data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +3 -5
- data/lib/cuke_modeler/adapters/gherkin_base_adapter.rb +14 -0
- data/lib/cuke_modeler/nested.rb +1 -0
- data/lib/cuke_modeler/parsing.rb +23 -2
- data/lib/cuke_modeler/version.rb +1 -1
- metadata +24 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c9ac27087020268412ee7784a9116dfe565cfb3d116db74e944e943045500c1
|
|
4
|
+
data.tar.gz: be5f5b5800ec74dbdebb4a03f3855dbfa0729ea3bd16f9f58696e922f0373fbd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 45b9e36b3cdf1277deeadc492ad092bcd941785a1953edaae9f3d0a6851daba9dbf2948f0889849b38c4d9d1ac8a3dba950e12f15a9d87fe7cdc20c49dad260c
|
|
7
|
+
data.tar.gz: a83024fbd6e3750dd06896475194fc2db3b102abeb2ea10946ef3d7150b60882e1e20ceec845f2b37d3faf54d578c17c9b3c7abaeb580968d0bd9100846c4186
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
|
|
9
9
|
Nothing yet...
|
|
10
10
|
|
|
11
|
+
## [3.11.0] - 2021-07-31
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Support added for more versions of the `cucumber-gherkin` gem
|
|
15
|
+
- 20.x
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- `Rule` models are now returnable from `Model#get_ancestor()`. Updating that method was missed when `Rule` models
|
|
19
|
+
were first added.
|
|
11
20
|
|
|
12
21
|
## [3.10.0] - 2021-05-28
|
|
13
22
|
|
|
@@ -387,7 +396,8 @@ Nothing yet...
|
|
|
387
396
|
- Initial release
|
|
388
397
|
|
|
389
398
|
|
|
390
|
-
[Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.
|
|
399
|
+
[Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.11.0...HEAD
|
|
400
|
+
[3.11.0]: https://github.com/enkessler/cuke_modeler/compare/v3.10.0...v3.11.0
|
|
391
401
|
[3.10.0]: https://github.com/enkessler/cuke_modeler/compare/v3.9.0...v3.10.0
|
|
392
402
|
[3.9.0]: https://github.com/enkessler/cuke_modeler/compare/v3.8.0...v3.9.0
|
|
393
403
|
[3.8.0]: https://github.com/enkessler/cuke_modeler/compare/v3.7.0...v3.8.0
|
data/README.md
CHANGED
|
@@ -8,8 +8,7 @@ User stuff:
|
|
|
8
8
|
[](https://www.rubydoc.info/gems/cuke_modeler)
|
|
9
9
|
|
|
10
10
|
Developer stuff:
|
|
11
|
-
[](https://ci.appveyor.com/project/enkessler/cuke-modeler)
|
|
11
|
+
[](https://github.com/enkessler/cuke_modeler/actions/workflows/ci.yml?query=branch%3Amaster)
|
|
13
12
|
[](https://coveralls.io/github/enkessler/cuke_modeler?branch=master)
|
|
14
13
|
[](https://codeclimate.com/github/enkessler/cuke_modeler/maintainability)
|
|
15
14
|
[](https://inch-ci.org/github/enkessler/cuke_modeler)
|
data/cuke_modeler.gemspec
CHANGED
|
@@ -36,11 +36,10 @@ Gem::Specification.new do |spec|
|
|
|
36
36
|
|
|
37
37
|
spec.required_ruby_version = '>= 2.3', '< 4.0'
|
|
38
38
|
|
|
39
|
-
spec.add_runtime_dependency 'cucumber-gherkin', '<
|
|
39
|
+
spec.add_runtime_dependency 'cucumber-gherkin', '< 21.0'
|
|
40
40
|
|
|
41
41
|
spec.add_development_dependency 'bundler', '< 3.0'
|
|
42
42
|
spec.add_development_dependency 'childprocess', '< 5.0'
|
|
43
|
-
spec.add_development_dependency 'coveralls', '< 1.0.0'
|
|
44
43
|
spec.add_development_dependency 'ffi', '< 2.0' # This is an invisible dependency for the `childprocess` gem on Windows
|
|
45
44
|
# Cucumber 4.x is the earliest version to use cucumber-gherkin
|
|
46
45
|
spec.add_development_dependency 'cucumber', '>= 4.0.0', '< 7.0.0'
|
|
@@ -50,8 +49,8 @@ Gem::Specification.new do |spec|
|
|
|
50
49
|
# RuboCop drops Ruby 2.3 support after this version and we need to maintain Ruby 2.3 compatibility when writing code
|
|
51
50
|
# for this gem
|
|
52
51
|
spec.add_development_dependency 'rubocop', '< 0.82.0'
|
|
53
|
-
|
|
54
|
-
spec.add_development_dependency 'simplecov', '
|
|
52
|
+
spec.add_development_dependency 'simplecov', '< 1.0'
|
|
53
|
+
spec.add_development_dependency 'simplecov-lcov', '< 1.0'
|
|
55
54
|
spec.add_development_dependency 'test-unit', '< 4.0.0'
|
|
56
55
|
spec.add_development_dependency 'yard', '< 1.0'
|
|
57
56
|
end
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
require_relative 'gherkin_base_adapter'
|
|
2
|
+
|
|
3
|
+
# Some things just aren't going to get better due to the inherent complexity of the AST
|
|
4
|
+
# rubocop:disable Metrics/ClassLength, Metrics/AbcSize, Metrics/MethodLength
|
|
5
|
+
|
|
6
|
+
module CukeModeler
|
|
7
|
+
|
|
8
|
+
# NOT A PART OF THE PUBLIC API
|
|
9
|
+
# An adapter that can convert the output of version 20.x of the *cucumber-gherkin* gem into input that is consumable
|
|
10
|
+
# by this gem.
|
|
11
|
+
class Gherkin20Adapter < GherkinBaseAdapter
|
|
12
|
+
|
|
13
|
+
# Adapts the given AST into the shape that this gem expects
|
|
14
|
+
def adapt(ast)
|
|
15
|
+
adapted_ast = {}
|
|
16
|
+
|
|
17
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
18
|
+
save_original_data(adapted_ast, ast)
|
|
19
|
+
clear_child_elements(adapted_ast, [[:feature], [:comments]])
|
|
20
|
+
|
|
21
|
+
adapted_ast['comments'] = adapt_comments(ast)
|
|
22
|
+
adapted_ast['feature'] = adapt_feature(ast.feature)
|
|
23
|
+
|
|
24
|
+
adapted_ast
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Adapts the AST sub-tree that is rooted at the given feature node.
|
|
28
|
+
def adapt_feature(feature_ast)
|
|
29
|
+
return nil unless feature_ast
|
|
30
|
+
|
|
31
|
+
adapted_feature = {}
|
|
32
|
+
|
|
33
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
34
|
+
save_original_data(adapted_feature, feature_ast)
|
|
35
|
+
clear_child_elements(adapted_feature, [[:tags],
|
|
36
|
+
[:children]])
|
|
37
|
+
|
|
38
|
+
adapted_feature['keyword'] = feature_ast.keyword
|
|
39
|
+
adapted_feature['name'] = feature_ast.name
|
|
40
|
+
adapted_feature['description'] = feature_ast.description
|
|
41
|
+
adapted_feature['line'] = feature_ast.location.line
|
|
42
|
+
|
|
43
|
+
adapted_feature['elements'] = adapt_child_elements(feature_ast)
|
|
44
|
+
adapted_feature['tags'] = adapt_tags(feature_ast)
|
|
45
|
+
|
|
46
|
+
adapted_feature
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Adapts the AST sub-tree that is rooted at the given background node.
|
|
50
|
+
def adapt_background(background_ast)
|
|
51
|
+
adapted_background = {}
|
|
52
|
+
|
|
53
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
54
|
+
save_original_data(adapted_background, background_ast)
|
|
55
|
+
clear_child_elements(adapted_background, [[:background, :steps]])
|
|
56
|
+
|
|
57
|
+
adapted_background['type'] = 'Background'
|
|
58
|
+
adapted_background['keyword'] = background_ast.background.keyword
|
|
59
|
+
adapted_background['name'] = background_ast.background.name
|
|
60
|
+
adapted_background['description'] = background_ast.background.description
|
|
61
|
+
adapted_background['line'] = background_ast.background.location.line
|
|
62
|
+
|
|
63
|
+
adapted_background['steps'] = adapt_steps(background_ast.background)
|
|
64
|
+
|
|
65
|
+
adapted_background
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Adapts the AST sub-tree that is rooted at the given rule node.
|
|
69
|
+
def adapt_rule(rule_ast)
|
|
70
|
+
adapted_rule = {}
|
|
71
|
+
|
|
72
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
73
|
+
save_original_data(adapted_rule, rule_ast)
|
|
74
|
+
clear_child_elements(adapted_rule, [[:rule, :tags],
|
|
75
|
+
[:rule, :children]])
|
|
76
|
+
|
|
77
|
+
adapted_rule['type'] = 'Rule'
|
|
78
|
+
adapted_rule['keyword'] = rule_ast.rule.keyword
|
|
79
|
+
adapted_rule['name'] = rule_ast.rule.name
|
|
80
|
+
adapted_rule['description'] = rule_ast.rule.description
|
|
81
|
+
adapted_rule['line'] = rule_ast.rule.location.line
|
|
82
|
+
|
|
83
|
+
adapted_rule['elements'] = adapt_child_elements(rule_ast.rule)
|
|
84
|
+
adapted_rule['tags'] = adapt_tags(rule_ast.rule)
|
|
85
|
+
|
|
86
|
+
adapted_rule
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Adapts the AST sub-tree that is rooted at the given scenario node.
|
|
90
|
+
def adapt_scenario(test_ast)
|
|
91
|
+
adapted_scenario = {}
|
|
92
|
+
|
|
93
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
94
|
+
save_original_data(adapted_scenario, test_ast)
|
|
95
|
+
clear_child_elements(adapted_scenario, [[:scenario, :tags],
|
|
96
|
+
[:scenario, :steps]])
|
|
97
|
+
|
|
98
|
+
adapted_scenario['type'] = 'Scenario'
|
|
99
|
+
adapted_scenario['keyword'] = test_ast.scenario.keyword
|
|
100
|
+
adapted_scenario['name'] = test_ast.scenario.name
|
|
101
|
+
adapted_scenario['description'] = test_ast.scenario.description
|
|
102
|
+
adapted_scenario['line'] = test_ast.scenario.location.line
|
|
103
|
+
|
|
104
|
+
adapted_scenario['tags'] = adapt_tags(test_ast.scenario)
|
|
105
|
+
adapted_scenario['steps'] = adapt_steps(test_ast.scenario)
|
|
106
|
+
|
|
107
|
+
adapted_scenario
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Adapts the AST sub-tree that is rooted at the given outline node.
|
|
111
|
+
def adapt_outline(test_ast)
|
|
112
|
+
adapted_outline = {}
|
|
113
|
+
|
|
114
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
115
|
+
save_original_data(adapted_outline, test_ast)
|
|
116
|
+
clear_child_elements(adapted_outline, [[:scenario, :tags],
|
|
117
|
+
[:scenario, :steps],
|
|
118
|
+
[:scenario, :examples]])
|
|
119
|
+
|
|
120
|
+
adapted_outline['type'] = 'ScenarioOutline'
|
|
121
|
+
adapted_outline['keyword'] = test_ast.scenario.keyword
|
|
122
|
+
adapted_outline['name'] = test_ast.scenario.name
|
|
123
|
+
adapted_outline['description'] = test_ast.scenario.description
|
|
124
|
+
adapted_outline['line'] = test_ast.scenario.location.line
|
|
125
|
+
|
|
126
|
+
adapted_outline['tags'] = adapt_tags(test_ast.scenario)
|
|
127
|
+
adapted_outline['steps'] = adapt_steps(test_ast.scenario)
|
|
128
|
+
adapted_outline['examples'] = adapt_examples(test_ast.scenario)
|
|
129
|
+
|
|
130
|
+
adapted_outline
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Adapts the AST sub-tree that is rooted at the given example node.
|
|
134
|
+
def adapt_example(example_ast)
|
|
135
|
+
adapted_example = {}
|
|
136
|
+
|
|
137
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
138
|
+
save_original_data(adapted_example, example_ast)
|
|
139
|
+
clear_child_elements(adapted_example, [[:tags],
|
|
140
|
+
[:table_header],
|
|
141
|
+
[:table_body]])
|
|
142
|
+
|
|
143
|
+
adapted_example['keyword'] = example_ast.keyword
|
|
144
|
+
adapted_example['name'] = example_ast.name
|
|
145
|
+
adapted_example['line'] = example_ast.location.line
|
|
146
|
+
adapted_example['description'] = example_ast.description
|
|
147
|
+
|
|
148
|
+
adapted_example['rows'] = []
|
|
149
|
+
adapted_example['rows'] << adapt_table_row(example_ast.table_header) if example_ast.table_header
|
|
150
|
+
|
|
151
|
+
example_ast.table_body&.each do |row|
|
|
152
|
+
adapted_example['rows'] << adapt_table_row(row)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
adapted_example['tags'] = adapt_tags(example_ast)
|
|
156
|
+
|
|
157
|
+
adapted_example
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Adapts the AST sub-tree that is rooted at the given tag node.
|
|
161
|
+
def adapt_tag(tag_ast)
|
|
162
|
+
adapted_tag = {}
|
|
163
|
+
|
|
164
|
+
# Saving off the original data
|
|
165
|
+
save_original_data(adapted_tag, tag_ast)
|
|
166
|
+
|
|
167
|
+
adapted_tag['name'] = tag_ast.name
|
|
168
|
+
adapted_tag['line'] = tag_ast.location.line
|
|
169
|
+
|
|
170
|
+
adapted_tag
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Adapts the AST sub-tree that is rooted at the given comment node.
|
|
174
|
+
def adapt_comment(comment_ast)
|
|
175
|
+
adapted_comment = {}
|
|
176
|
+
|
|
177
|
+
# Saving off the original data
|
|
178
|
+
save_original_data(adapted_comment, comment_ast)
|
|
179
|
+
|
|
180
|
+
adapted_comment['text'] = comment_ast.text
|
|
181
|
+
adapted_comment['line'] = comment_ast.location.line
|
|
182
|
+
|
|
183
|
+
adapted_comment
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Adapts the AST sub-tree that is rooted at the given step node.
|
|
187
|
+
def adapt_step(step_ast)
|
|
188
|
+
adapted_step = {}
|
|
189
|
+
|
|
190
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
191
|
+
save_original_data(adapted_step, step_ast)
|
|
192
|
+
clear_child_elements(adapted_step, [[:data_table],
|
|
193
|
+
[:doc_string]])
|
|
194
|
+
|
|
195
|
+
adapted_step['keyword'] = step_ast.keyword
|
|
196
|
+
adapted_step['name'] = step_ast.text
|
|
197
|
+
adapted_step['line'] = step_ast.location.line
|
|
198
|
+
|
|
199
|
+
if step_ast.doc_string
|
|
200
|
+
adapted_step['doc_string'] = adapt_doc_string(step_ast.doc_string)
|
|
201
|
+
elsif step_ast.data_table
|
|
202
|
+
adapted_step['table'] = adapt_step_table(step_ast.data_table)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
adapted_step
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Adapts the AST sub-tree that is rooted at the given doc string node.
|
|
209
|
+
def adapt_doc_string(doc_string_ast)
|
|
210
|
+
adapted_doc_string = {}
|
|
211
|
+
|
|
212
|
+
# Saving off the original data
|
|
213
|
+
save_original_data(adapted_doc_string, doc_string_ast)
|
|
214
|
+
|
|
215
|
+
adapted_doc_string['value'] = doc_string_ast.content
|
|
216
|
+
adapted_doc_string['content_type'] = doc_string_ast.media_type
|
|
217
|
+
adapted_doc_string['line'] = doc_string_ast.location.line
|
|
218
|
+
|
|
219
|
+
adapted_doc_string
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Adapts the AST sub-tree that is rooted at the given table node.
|
|
223
|
+
def adapt_step_table(step_table_ast)
|
|
224
|
+
adapted_step_table = {}
|
|
225
|
+
|
|
226
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
227
|
+
save_original_data(adapted_step_table, step_table_ast)
|
|
228
|
+
clear_child_elements(adapted_step_table, [[:rows]])
|
|
229
|
+
|
|
230
|
+
adapted_step_table['rows'] = []
|
|
231
|
+
step_table_ast.rows.each do |row|
|
|
232
|
+
adapted_step_table['rows'] << adapt_table_row(row)
|
|
233
|
+
end
|
|
234
|
+
adapted_step_table['line'] = step_table_ast.location.line
|
|
235
|
+
|
|
236
|
+
adapted_step_table
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Adapts the AST sub-tree that is rooted at the given row node.
|
|
240
|
+
def adapt_table_row(table_row_ast)
|
|
241
|
+
adapted_table_row = {}
|
|
242
|
+
|
|
243
|
+
# Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
|
|
244
|
+
save_original_data(adapted_table_row, table_row_ast)
|
|
245
|
+
clear_child_elements(adapted_table_row, [[:cells]])
|
|
246
|
+
|
|
247
|
+
adapted_table_row['line'] = table_row_ast.location.line
|
|
248
|
+
|
|
249
|
+
adapted_table_row['cells'] = []
|
|
250
|
+
table_row_ast.cells.each do |row|
|
|
251
|
+
adapted_table_row['cells'] << adapt_table_cell(row)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
adapted_table_row
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Adapts the AST sub-tree that is rooted at the given cell node.
|
|
258
|
+
def adapt_table_cell(cell_ast)
|
|
259
|
+
adapted_cell = {}
|
|
260
|
+
|
|
261
|
+
# Saving off the original data
|
|
262
|
+
save_original_data(adapted_cell, cell_ast)
|
|
263
|
+
|
|
264
|
+
adapted_cell['value'] = cell_ast.value
|
|
265
|
+
adapted_cell['line'] = cell_ast.location.line
|
|
266
|
+
|
|
267
|
+
adapted_cell
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
private
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def adapt_comments(file_ast)
|
|
275
|
+
file_ast.comments.map { |comment| adapt_comment(comment) }
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def adapt_tags(element_ast)
|
|
279
|
+
element_ast.tags.map { |tag| adapt_tag(tag) }
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def adapt_steps(element_ast)
|
|
283
|
+
element_ast.steps.map { |step| adapt_step(step) }
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def adapt_examples(element_ast)
|
|
287
|
+
element_ast.examples.map { |example| adapt_example(example) }
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def adapt_child_elements(element_ast)
|
|
291
|
+
adapted_children = []
|
|
292
|
+
|
|
293
|
+
element_ast.children.each do |child_element|
|
|
294
|
+
adapted_children << if child_element.background
|
|
295
|
+
adapt_background(child_element)
|
|
296
|
+
elsif child_element.respond_to?(:rule) && child_element.rule
|
|
297
|
+
adapt_rule(child_element)
|
|
298
|
+
else
|
|
299
|
+
adapt_test(child_element)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
adapted_children
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def adapt_test(test_ast)
|
|
307
|
+
if test_has_examples?(test_ast) || test_uses_outline_keyword?(test_ast)
|
|
308
|
+
adapt_outline(test_ast)
|
|
309
|
+
else
|
|
310
|
+
adapt_scenario(test_ast)
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def clear_child_elements(ast, child_paths)
|
|
315
|
+
# rubocop:disable Security/Eval - This is not blind data
|
|
316
|
+
child_paths.each do |traversal_path|
|
|
317
|
+
# Wipe the value if it's there but don't add any attributes to the object if it didn't already have them
|
|
318
|
+
if eval("ast['cuke_modeler_parsing_data'].#{traversal_path.join('.')}", binding, __FILE__, __LINE__)
|
|
319
|
+
property_path = traversal_path[0..-2].join('.')
|
|
320
|
+
eval("ast['cuke_modeler_parsing_data']#{property_path.empty? ? '' : '.' + property_path}.instance_variable_set(\"@#{traversal_path.last}\", nil)", binding, __FILE__, __LINE__) # rubocop:disable Layout/LineLength
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
# rubocop:enable Security/Eval
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def test_has_examples?(ast_node)
|
|
327
|
+
ast_node.scenario.examples.any?
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def test_uses_outline_keyword?(test_ast)
|
|
331
|
+
Parsing.dialects[Parsing.dialect]['scenarioOutline'].include?(test_ast.scenario.keyword)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# rubocop:enable Metrics/ClassLength, Metrics/AbcSize, Metrics/MethodLength
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative 'gherkin_base_adapter'
|
|
2
|
+
|
|
1
3
|
# Some things just aren't going to get better due to the inherent complexity of the AST
|
|
2
4
|
# rubocop:disable Metrics/ClassLength, Metrics/AbcSize, Metrics/MethodLength
|
|
3
5
|
|
|
@@ -6,7 +8,7 @@ module CukeModeler
|
|
|
6
8
|
# NOT A PART OF THE PUBLIC API
|
|
7
9
|
# An adapter that can convert the output of version 9.x of the *cucumber-gherkin* gem into input that is consumable
|
|
8
10
|
# by this gem.
|
|
9
|
-
class Gherkin9Adapter
|
|
11
|
+
class Gherkin9Adapter < GherkinBaseAdapter
|
|
10
12
|
|
|
11
13
|
# Adapts the given AST into the shape that this gem expects
|
|
12
14
|
def adapt(ast)
|
|
@@ -322,10 +324,6 @@ module CukeModeler
|
|
|
322
324
|
end
|
|
323
325
|
end
|
|
324
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
327
|
def clear_child_elements(ast, child_paths)
|
|
330
328
|
child_paths.each do |traversal_path|
|
|
331
329
|
# Wipe the value if it's there but don't add any keys to the hash if it didn't already have them
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module CukeModeler
|
|
2
|
+
|
|
3
|
+
# NOT A PART OF THE PUBLIC API
|
|
4
|
+
# A class providing some basic and common adapter functionality.
|
|
5
|
+
class GherkinBaseAdapter
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def save_original_data(adapted_ast, raw_ast)
|
|
10
|
+
adapted_ast['cuke_modeler_parsing_data'] = Marshal.load(Marshal.dump(raw_ast))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/cuke_modeler/nested.rb
CHANGED
data/lib/cuke_modeler/parsing.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# rubocop:disable Metrics/ModuleLength - Just not going to worry about this
|
|
2
|
+
|
|
1
3
|
# Have to at least load some version of the gem before which version of the gem has been loaded can
|
|
2
4
|
# be determined and the rest of the needed files can be loaded.
|
|
3
5
|
require 'gherkin'
|
|
@@ -7,7 +9,7 @@ require 'gherkin'
|
|
|
7
9
|
# an 'adapter' appropriate to the version of the *cucumber-gherkin* gem that has been activated.
|
|
8
10
|
gherkin_version = Gem.loaded_specs['cucumber-gherkin'].version.version
|
|
9
11
|
gherkin_major_version = gherkin_version.match(/^(\d+)\./)[1].to_i
|
|
10
|
-
supported_gherkin_versions = (9..
|
|
12
|
+
supported_gherkin_versions = (9..20)
|
|
11
13
|
|
|
12
14
|
raise("Unknown Gherkin version: '#{gherkin_version}'") unless supported_gherkin_versions.include?(gherkin_major_version)
|
|
13
15
|
|
|
@@ -32,7 +34,7 @@ module CukeModeler
|
|
|
32
34
|
|
|
33
35
|
# The dialects currently known by the gherkin gem
|
|
34
36
|
def dialects
|
|
35
|
-
|
|
37
|
+
Gherkin::DIALECTS
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
# Parses the Cucumber feature given in *source_text* and returns a hash representation of
|
|
@@ -61,6 +63,23 @@ module CukeModeler
|
|
|
61
63
|
# inside of it, so I'm leaving this here in case it changes again
|
|
62
64
|
# rubocop:disable Lint/DuplicateMethods
|
|
63
65
|
case gherkin_major_version
|
|
66
|
+
when 20
|
|
67
|
+
# TODO: make these methods private?
|
|
68
|
+
# NOT A PART OF THE PUBLIC API
|
|
69
|
+
# The method to use for parsing Gherkin text
|
|
70
|
+
def parsing_method(source_text, filename)
|
|
71
|
+
messages = Gherkin.from_source(filename,
|
|
72
|
+
source_text,
|
|
73
|
+
{ include_gherkin_document: true })
|
|
74
|
+
.to_a
|
|
75
|
+
|
|
76
|
+
error_message = messages.find(&:parse_error)
|
|
77
|
+
gherkin_ast_message = messages.find(&:gherkin_document)
|
|
78
|
+
|
|
79
|
+
raise error_message.parse_error.message if error_message
|
|
80
|
+
|
|
81
|
+
gherkin_ast_message.gherkin_document
|
|
82
|
+
end
|
|
64
83
|
when 19
|
|
65
84
|
# TODO: make these methods private?
|
|
66
85
|
# NOT A PART OF THE PUBLIC API
|
|
@@ -175,3 +194,5 @@ module CukeModeler
|
|
|
175
194
|
|
|
176
195
|
end
|
|
177
196
|
end
|
|
197
|
+
|
|
198
|
+
# rubocop:enable Metrics/ModuleLength
|
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.11.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: 2021-
|
|
11
|
+
date: 2021-07-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cucumber-gherkin
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "<"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '21.0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "<"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '21.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -52,20 +52,6 @@ dependencies:
|
|
|
52
52
|
- - "<"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '5.0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: coveralls
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "<"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: 1.0.0
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "<"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: 1.0.0
|
|
69
55
|
- !ruby/object:Gem::Dependency
|
|
70
56
|
name: ffi
|
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -160,16 +146,30 @@ dependencies:
|
|
|
160
146
|
name: simplecov
|
|
161
147
|
requirement: !ruby/object:Gem::Requirement
|
|
162
148
|
requirements:
|
|
163
|
-
- - "
|
|
149
|
+
- - "<"
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '1.0'
|
|
152
|
+
type: :development
|
|
153
|
+
prerelease: false
|
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
155
|
+
requirements:
|
|
156
|
+
- - "<"
|
|
157
|
+
- !ruby/object:Gem::Version
|
|
158
|
+
version: '1.0'
|
|
159
|
+
- !ruby/object:Gem::Dependency
|
|
160
|
+
name: simplecov-lcov
|
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
|
162
|
+
requirements:
|
|
163
|
+
- - "<"
|
|
164
164
|
- !ruby/object:Gem::Version
|
|
165
|
-
version: 0
|
|
165
|
+
version: '1.0'
|
|
166
166
|
type: :development
|
|
167
167
|
prerelease: false
|
|
168
168
|
version_requirements: !ruby/object:Gem::Requirement
|
|
169
169
|
requirements:
|
|
170
|
-
- - "
|
|
170
|
+
- - "<"
|
|
171
171
|
- !ruby/object:Gem::Version
|
|
172
|
-
version: 0
|
|
172
|
+
version: '1.0'
|
|
173
173
|
- !ruby/object:Gem::Dependency
|
|
174
174
|
name: test-unit
|
|
175
175
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -226,7 +226,9 @@ files:
|
|
|
226
226
|
- lib/cuke_modeler/adapters/gherkin_17_adapter.rb
|
|
227
227
|
- lib/cuke_modeler/adapters/gherkin_18_adapter.rb
|
|
228
228
|
- lib/cuke_modeler/adapters/gherkin_19_adapter.rb
|
|
229
|
+
- lib/cuke_modeler/adapters/gherkin_20_adapter.rb
|
|
229
230
|
- lib/cuke_modeler/adapters/gherkin_9_adapter.rb
|
|
231
|
+
- lib/cuke_modeler/adapters/gherkin_base_adapter.rb
|
|
230
232
|
- lib/cuke_modeler/containing.rb
|
|
231
233
|
- lib/cuke_modeler/described.rb
|
|
232
234
|
- lib/cuke_modeler/models/background.rb
|