cuke_modeler 3.10.0 → 3.14.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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -1
  3. data/README.md +1 -2
  4. data/cuke_modeler.gemspec +3 -4
  5. data/lib/cuke_modeler/adapters/gherkin_20_adapter.rb +350 -0
  6. data/lib/cuke_modeler/adapters/gherkin_21_adapter.rb +13 -0
  7. data/lib/cuke_modeler/adapters/gherkin_22_adapter.rb +13 -0
  8. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +16 -5
  9. data/lib/cuke_modeler/adapters/gherkin_base_adapter.rb +14 -0
  10. data/lib/cuke_modeler/containing.rb +13 -13
  11. data/lib/cuke_modeler/nested.rb +1 -0
  12. data/lib/cuke_modeler/parsing.rb +23 -2
  13. data/lib/cuke_modeler/sourceable.rb +4 -1
  14. data/lib/cuke_modeler/version.rb +1 -1
  15. data/testing/cucumber/features/modeling/background_modeling.feature +28 -5
  16. data/testing/cucumber/features/modeling/cell_modeling.feature +46 -0
  17. data/testing/cucumber/features/modeling/comment_modeling.feature +20 -0
  18. data/testing/cucumber/features/modeling/doc_string_modeling.feature +26 -0
  19. data/testing/cucumber/features/modeling/example_modeling.feature +25 -0
  20. data/testing/cucumber/features/modeling/feature_modeling.feature +7 -0
  21. data/testing/cucumber/features/modeling/outline_modeling.feature +26 -1
  22. data/testing/cucumber/features/modeling/row_modeling.feature +23 -0
  23. data/testing/cucumber/features/modeling/rule_modeling.feature +21 -0
  24. data/testing/cucumber/features/modeling/scenario_modeling.feature +22 -0
  25. data/testing/cucumber/features/modeling/step_modeling.feature +22 -0
  26. data/testing/cucumber/features/modeling/table_modeling.feature +24 -0
  27. data/testing/cucumber/features/modeling/tag_modeling.feature +20 -0
  28. metadata +26 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7821b738cb9b7436e38de701654c9ca04d087ba2e482f01af0600f86383b47d
4
- data.tar.gz: 8b71afb721c52cc198243a468807547d45254dab84dd5bafcbec49e9bb4befb0
3
+ metadata.gz: 42e13fd543b846c0dfd1120e67c157aefb71eeeae7bc68894686813368aace1a
4
+ data.tar.gz: 676f7198e3746318b0f4a2d79c3a8c410ebcbab00b3e543dbb225cfaa8f4ee58
5
5
  SHA512:
6
- metadata.gz: f114b4de2f4f2ef4ffd95078c7b8f72db2318174a75c4d4ed86a900ed21585e91e918afe97770afc1857b3cc80c904e471717f59a90c814bd7664575879e07e8
7
- data.tar.gz: e870f0c73a8f296f6c8b108956d787586e9f47b3a2bff78db9a10db58c8df2ffc39fed04a1ace3629911c03f36ac6aee6c3e74475c60c58d7d0416f141d07037
6
+ metadata.gz: 8500092bdeeb98f81134b8e3302ddf796acd867ccd1324b09d2d75103902b6a926d1220ddbaf08aea98624fe64f1246804868fee21e56a9ec24766c0695455f3
7
+ data.tar.gz: 939fc0d59e4cf3cc194ac28f51a140c928e4ce61f493cc21b03b9a9140c80981fc9e25dbadaa46a4c09f187b8610f37d76a52b708f2ca6434500b2f7324bca7c
data/CHANGELOG.md CHANGED
@@ -8,6 +8,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  Nothing yet...
10
10
 
11
+ ## [3.14.0] - 2021-11-22
12
+
13
+ ### Added
14
+ - All models for Gherkin elements now track the column number from which they originate in a source file.
15
+
16
+ ## [3.13.0] - 2021-09-25
17
+
18
+ ### Added
19
+ - Support added for more versions of the `cucumber-gherkin` gem
20
+ - 22.x
21
+
22
+ ## [3.12.0] - 2021-09-09
23
+
24
+ ### Added
25
+ - Support added for more versions of the `cucumber-gherkin` gem
26
+ - 21.x
27
+
28
+ ## [3.11.0] - 2021-07-31
29
+
30
+ ### Added
31
+ - Support added for more versions of the `cucumber-gherkin` gem
32
+ - 20.x
33
+
34
+ ### Fixed
35
+ - `Rule` models are now returnable from `Model#get_ancestor()`. Updating that method was missed when `Rule` models
36
+ were first added.
11
37
 
12
38
  ## [3.10.0] - 2021-05-28
13
39
 
@@ -387,7 +413,11 @@ Nothing yet...
387
413
  - Initial release
388
414
 
389
415
 
390
- [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.10.0...HEAD
416
+ [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.14.0...HEAD
417
+ [3.14.0]: https://github.com/enkessler/cuke_modeler/compare/v3.13.0...v3.14.0
418
+ [3.13.0]: https://github.com/enkessler/cuke_modeler/compare/v3.12.0...v3.13.0
419
+ [3.12.0]: https://github.com/enkessler/cuke_modeler/compare/v3.11.0...v3.12.0
420
+ [3.11.0]: https://github.com/enkessler/cuke_modeler/compare/v3.10.0...v3.11.0
391
421
  [3.10.0]: https://github.com/enkessler/cuke_modeler/compare/v3.9.0...v3.10.0
392
422
  [3.9.0]: https://github.com/enkessler/cuke_modeler/compare/v3.8.0...v3.9.0
393
423
  [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
  [![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?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)
11
+ [![Build Status](https://github.com/enkessler/cuke_modeler/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/enkessler/cuke_modeler/actions/workflows/ci.yml?query=branch%3Amaster)
13
12
  [![Coverage Status](https://coveralls.io/repos/github/enkessler/cuke_modeler/badge.svg?branch=master)](https://coveralls.io/github/enkessler/cuke_modeler?branch=master)
14
13
  [![Maintainability](https://api.codeclimate.com/v1/badges/83986d8f7a918fed9707/maintainability)](https://codeclimate.com/github/enkessler/cuke_modeler/maintainability)
15
14
  [![Inline docs](http://inch-ci.org/github/enkessler/cuke_modeler.svg?branch=master)](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', '< 20.0'
39
+ spec.add_runtime_dependency 'cucumber-gherkin', '< 23.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
- # Coveralls gem does not support any newer version than this
54
- spec.add_development_dependency 'simplecov', '<= 0.16.1'
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,350 @@
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
+ adapted_feature['column'] = feature_ast.location.column
43
+
44
+ adapted_feature['elements'] = adapt_child_elements(feature_ast)
45
+ adapted_feature['tags'] = adapt_tags(feature_ast)
46
+
47
+ adapted_feature
48
+ end
49
+
50
+ # Adapts the AST sub-tree that is rooted at the given background node.
51
+ def adapt_background(background_ast)
52
+ adapted_background = {}
53
+
54
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
55
+ save_original_data(adapted_background, background_ast)
56
+ clear_child_elements(adapted_background, [[:background, :steps]])
57
+
58
+ adapted_background['type'] = 'Background'
59
+ adapted_background['keyword'] = background_ast.background.keyword
60
+ adapted_background['name'] = background_ast.background.name
61
+ adapted_background['description'] = background_ast.background.description
62
+ adapted_background['line'] = background_ast.background.location.line
63
+ adapted_background['column'] = background_ast.background.location.column
64
+
65
+ adapted_background['steps'] = adapt_steps(background_ast.background)
66
+
67
+ adapted_background
68
+ end
69
+
70
+ # Adapts the AST sub-tree that is rooted at the given rule node.
71
+ def adapt_rule(rule_ast)
72
+ adapted_rule = {}
73
+
74
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
75
+ save_original_data(adapted_rule, rule_ast)
76
+ clear_child_elements(adapted_rule, [[:rule, :tags],
77
+ [:rule, :children]])
78
+
79
+ adapted_rule['type'] = 'Rule'
80
+ adapted_rule['keyword'] = rule_ast.rule.keyword
81
+ adapted_rule['name'] = rule_ast.rule.name
82
+ adapted_rule['description'] = rule_ast.rule.description
83
+ adapted_rule['line'] = rule_ast.rule.location.line
84
+ adapted_rule['column'] = rule_ast.rule.location.column
85
+
86
+ adapted_rule['elements'] = adapt_child_elements(rule_ast.rule)
87
+ adapted_rule['tags'] = adapt_tags(rule_ast.rule)
88
+
89
+ adapted_rule
90
+ end
91
+
92
+ # Adapts the AST sub-tree that is rooted at the given scenario node.
93
+ def adapt_scenario(test_ast)
94
+ adapted_scenario = {}
95
+
96
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
97
+ save_original_data(adapted_scenario, test_ast)
98
+ clear_child_elements(adapted_scenario, [[:scenario, :tags],
99
+ [:scenario, :steps]])
100
+
101
+ adapted_scenario['type'] = 'Scenario'
102
+ adapted_scenario['keyword'] = test_ast.scenario.keyword
103
+ adapted_scenario['name'] = test_ast.scenario.name
104
+ adapted_scenario['description'] = test_ast.scenario.description
105
+ adapted_scenario['line'] = test_ast.scenario.location.line
106
+ adapted_scenario['column'] = test_ast.scenario.location.column
107
+
108
+ adapted_scenario['tags'] = adapt_tags(test_ast.scenario)
109
+ adapted_scenario['steps'] = adapt_steps(test_ast.scenario)
110
+
111
+ adapted_scenario
112
+ end
113
+
114
+ # Adapts the AST sub-tree that is rooted at the given outline node.
115
+ def adapt_outline(test_ast)
116
+ adapted_outline = {}
117
+
118
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
119
+ save_original_data(adapted_outline, test_ast)
120
+ clear_child_elements(adapted_outline, [[:scenario, :tags],
121
+ [:scenario, :steps],
122
+ [:scenario, :examples]])
123
+
124
+ adapted_outline['type'] = 'ScenarioOutline'
125
+ adapted_outline['keyword'] = test_ast.scenario.keyword
126
+ adapted_outline['name'] = test_ast.scenario.name
127
+ adapted_outline['description'] = test_ast.scenario.description
128
+ adapted_outline['line'] = test_ast.scenario.location.line
129
+ adapted_outline['column'] = test_ast.scenario.location.column
130
+
131
+ adapted_outline['tags'] = adapt_tags(test_ast.scenario)
132
+ adapted_outline['steps'] = adapt_steps(test_ast.scenario)
133
+ adapted_outline['examples'] = adapt_examples(test_ast.scenario)
134
+
135
+ adapted_outline
136
+ end
137
+
138
+ # Adapts the AST sub-tree that is rooted at the given example node.
139
+ def adapt_example(example_ast)
140
+ adapted_example = {}
141
+
142
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
143
+ save_original_data(adapted_example, example_ast)
144
+ clear_child_elements(adapted_example, [[:tags],
145
+ [:table_header],
146
+ [:table_body]])
147
+
148
+ adapted_example['keyword'] = example_ast.keyword
149
+ adapted_example['name'] = example_ast.name
150
+ adapted_example['line'] = example_ast.location.line
151
+ adapted_example['column'] = example_ast.location.column
152
+ adapted_example['description'] = example_ast.description
153
+
154
+ adapted_example['rows'] = []
155
+ adapted_example['rows'] << adapt_table_row(example_ast.table_header) if example_ast.table_header
156
+
157
+ example_ast.table_body&.each do |row|
158
+ adapted_example['rows'] << adapt_table_row(row)
159
+ end
160
+
161
+ adapted_example['tags'] = adapt_tags(example_ast)
162
+
163
+ adapted_example
164
+ end
165
+
166
+ # Adapts the AST sub-tree that is rooted at the given tag node.
167
+ def adapt_tag(tag_ast)
168
+ adapted_tag = {}
169
+
170
+ # Saving off the original data
171
+ save_original_data(adapted_tag, tag_ast)
172
+
173
+ adapted_tag['name'] = tag_ast.name
174
+ adapted_tag['line'] = tag_ast.location.line
175
+ adapted_tag['column'] = tag_ast.location.column
176
+
177
+ adapted_tag
178
+ end
179
+
180
+ # Adapts the AST sub-tree that is rooted at the given comment node.
181
+ def adapt_comment(comment_ast)
182
+ adapted_comment = {}
183
+
184
+ # Saving off the original data
185
+ save_original_data(adapted_comment, comment_ast)
186
+
187
+ adapted_comment['text'] = comment_ast.text
188
+ adapted_comment['line'] = comment_ast.location.line
189
+ adapted_comment['column'] = comment_ast.location.column
190
+
191
+ adapted_comment
192
+ end
193
+
194
+ # Adapts the AST sub-tree that is rooted at the given step node.
195
+ def adapt_step(step_ast)
196
+ adapted_step = {}
197
+
198
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
199
+ save_original_data(adapted_step, step_ast)
200
+ clear_child_elements(adapted_step, [[:data_table],
201
+ [:doc_string]])
202
+
203
+ adapted_step['keyword'] = step_ast.keyword
204
+ adapted_step['name'] = step_ast.text
205
+ adapted_step['line'] = step_ast.location.line
206
+ adapted_step['column'] = step_ast.location.column
207
+
208
+ if step_ast.doc_string
209
+ adapted_step['doc_string'] = adapt_doc_string(step_ast.doc_string)
210
+ elsif step_ast.data_table
211
+ adapted_step['table'] = adapt_step_table(step_ast.data_table)
212
+ end
213
+
214
+ adapted_step
215
+ end
216
+
217
+ # Adapts the AST sub-tree that is rooted at the given doc string node.
218
+ def adapt_doc_string(doc_string_ast)
219
+ adapted_doc_string = {}
220
+
221
+ # Saving off the original data
222
+ save_original_data(adapted_doc_string, doc_string_ast)
223
+
224
+ adapted_doc_string['value'] = doc_string_ast.content
225
+ adapted_doc_string['content_type'] = doc_string_ast.media_type
226
+ adapted_doc_string['line'] = doc_string_ast.location.line
227
+ adapted_doc_string['column'] = doc_string_ast.location.column
228
+
229
+ adapted_doc_string
230
+ end
231
+
232
+ # Adapts the AST sub-tree that is rooted at the given table node.
233
+ def adapt_step_table(step_table_ast)
234
+ adapted_step_table = {}
235
+
236
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
237
+ save_original_data(adapted_step_table, step_table_ast)
238
+ clear_child_elements(adapted_step_table, [[:rows]])
239
+
240
+ adapted_step_table['rows'] = []
241
+ step_table_ast.rows.each do |row|
242
+ adapted_step_table['rows'] << adapt_table_row(row)
243
+ end
244
+ adapted_step_table['line'] = step_table_ast.location.line
245
+ adapted_step_table['column'] = step_table_ast.location.column
246
+
247
+ adapted_step_table
248
+ end
249
+
250
+ # Adapts the AST sub-tree that is rooted at the given row node.
251
+ def adapt_table_row(table_row_ast)
252
+ adapted_table_row = {}
253
+
254
+ # Saving off the original data and removing parsed data for child elements in order to avoid duplicating data
255
+ save_original_data(adapted_table_row, table_row_ast)
256
+ clear_child_elements(adapted_table_row, [[:cells]])
257
+
258
+ adapted_table_row['line'] = table_row_ast.location.line
259
+ adapted_table_row['column'] = table_row_ast.location.column
260
+
261
+ adapted_table_row['cells'] = []
262
+ table_row_ast.cells.each do |row|
263
+ adapted_table_row['cells'] << adapt_table_cell(row)
264
+ end
265
+
266
+ adapted_table_row
267
+ end
268
+
269
+ # Adapts the AST sub-tree that is rooted at the given cell node.
270
+ def adapt_table_cell(cell_ast)
271
+ adapted_cell = {}
272
+
273
+ # Saving off the original data
274
+ save_original_data(adapted_cell, cell_ast)
275
+
276
+ adapted_cell['value'] = cell_ast.value
277
+ adapted_cell['line'] = cell_ast.location.line
278
+ adapted_cell['column'] = cell_ast.location.column
279
+
280
+ adapted_cell
281
+ end
282
+
283
+
284
+ private
285
+
286
+
287
+ def adapt_comments(file_ast)
288
+ file_ast.comments.map { |comment| adapt_comment(comment) }
289
+ end
290
+
291
+ def adapt_tags(element_ast)
292
+ element_ast.tags.map { |tag| adapt_tag(tag) }
293
+ end
294
+
295
+ def adapt_steps(element_ast)
296
+ element_ast.steps.map { |step| adapt_step(step) }
297
+ end
298
+
299
+ def adapt_examples(element_ast)
300
+ element_ast.examples.map { |example| adapt_example(example) }
301
+ end
302
+
303
+ def adapt_child_elements(element_ast)
304
+ adapted_children = []
305
+
306
+ element_ast.children.each do |child_element|
307
+ adapted_children << if child_element.background
308
+ adapt_background(child_element)
309
+ elsif child_element.respond_to?(:rule) && child_element.rule
310
+ adapt_rule(child_element)
311
+ else
312
+ adapt_test(child_element)
313
+ end
314
+ end
315
+
316
+ adapted_children
317
+ end
318
+
319
+ def adapt_test(test_ast)
320
+ if test_has_examples?(test_ast) || test_uses_outline_keyword?(test_ast)
321
+ adapt_outline(test_ast)
322
+ else
323
+ adapt_scenario(test_ast)
324
+ end
325
+ end
326
+
327
+ def clear_child_elements(ast, child_paths)
328
+ # rubocop:disable Security/Eval - This is not blind data
329
+ child_paths.each do |traversal_path|
330
+ # Wipe the value if it's there but don't add any attributes to the object if it didn't already have them
331
+ if eval("ast['cuke_modeler_parsing_data'].#{traversal_path.join('.')}", binding, __FILE__, __LINE__)
332
+ property_path = traversal_path[0..-2].join('.')
333
+ 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
334
+ end
335
+ end
336
+ # rubocop:enable Security/Eval
337
+ end
338
+
339
+ def test_has_examples?(ast_node)
340
+ ast_node.scenario.examples.any?
341
+ end
342
+
343
+ def test_uses_outline_keyword?(test_ast)
344
+ Parsing.dialects[Parsing.dialect]['scenarioOutline'].include?(test_ast.scenario.keyword)
345
+ end
346
+
347
+ end
348
+ end
349
+
350
+ # rubocop:enable Metrics/ClassLength, Metrics/AbcSize, Metrics/MethodLength
@@ -0,0 +1,13 @@
1
+ require_relative 'gherkin_20_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 21.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+
10
+ class Gherkin21Adapter < Gherkin20Adapter
11
+
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'gherkin_20_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 22.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+
10
+ class Gherkin22Adapter < Gherkin20Adapter
11
+
12
+ end
13
+ end
@@ -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)
@@ -38,6 +40,7 @@ module CukeModeler
38
40
  adapted_feature['name'] = feature_ast[:name]
39
41
  adapted_feature['description'] = feature_ast[:description] || ''
40
42
  adapted_feature['line'] = feature_ast[:location][:line]
43
+ adapted_feature['column'] = feature_ast[:location][:column]
41
44
 
42
45
  adapted_feature['elements'] = adapt_child_elements(feature_ast)
43
46
  adapted_feature['tags'] = adapt_tags(feature_ast)
@@ -58,6 +61,7 @@ module CukeModeler
58
61
  adapted_background['name'] = background_ast[:background][:name]
59
62
  adapted_background['description'] = background_ast[:background][:description] || ''
60
63
  adapted_background['line'] = background_ast[:background][:location][:line]
64
+ adapted_background['column'] = background_ast[:background][:location][:column]
61
65
 
62
66
  adapted_background['steps'] = adapt_steps(background_ast[:background])
63
67
 
@@ -77,6 +81,7 @@ module CukeModeler
77
81
  adapted_rule['name'] = rule_ast[:rule][:name]
78
82
  adapted_rule['description'] = rule_ast[:rule][:description] || ''
79
83
  adapted_rule['line'] = rule_ast[:rule][:location][:line]
84
+ adapted_rule['column'] = rule_ast[:rule][:location][:column]
80
85
 
81
86
  adapted_rule['elements'] = adapt_child_elements(rule_ast[:rule])
82
87
 
@@ -97,6 +102,7 @@ module CukeModeler
97
102
  adapted_scenario['name'] = test_ast[:scenario][:name]
98
103
  adapted_scenario['description'] = test_ast[:scenario][:description] || ''
99
104
  adapted_scenario['line'] = test_ast[:scenario][:location][:line]
105
+ adapted_scenario['column'] = test_ast[:scenario][:location][:column]
100
106
 
101
107
  adapted_scenario['tags'] = adapt_tags(test_ast[:scenario])
102
108
  adapted_scenario['steps'] = adapt_steps(test_ast[:scenario])
@@ -119,6 +125,7 @@ module CukeModeler
119
125
  adapted_outline['name'] = test_ast[:scenario][:name]
120
126
  adapted_outline['description'] = test_ast[:scenario][:description] || ''
121
127
  adapted_outline['line'] = test_ast[:scenario][:location][:line]
128
+ adapted_outline['column'] = test_ast[:scenario][:location][:column]
122
129
 
123
130
  adapted_outline['tags'] = adapt_tags(test_ast[:scenario])
124
131
  adapted_outline['steps'] = adapt_steps(test_ast[:scenario])
@@ -140,6 +147,7 @@ module CukeModeler
140
147
  adapted_example['keyword'] = example_ast[:keyword]
141
148
  adapted_example['name'] = example_ast[:name]
142
149
  adapted_example['line'] = example_ast[:location][:line]
150
+ adapted_example['column'] = example_ast[:location][:column]
143
151
  adapted_example['description'] = example_ast[:description] || ''
144
152
 
145
153
  adapted_example['rows'] = []
@@ -163,6 +171,7 @@ module CukeModeler
163
171
 
164
172
  adapted_tag['name'] = tag_ast[:name]
165
173
  adapted_tag['line'] = tag_ast[:location][:line]
174
+ adapted_tag['column'] = tag_ast[:location][:column]
166
175
 
167
176
  adapted_tag
168
177
  end
@@ -176,6 +185,7 @@ module CukeModeler
176
185
 
177
186
  adapted_comment['text'] = comment_ast[:text]
178
187
  adapted_comment['line'] = comment_ast[:location][:line]
188
+ adapted_comment['column'] = comment_ast[:location][:column]
179
189
 
180
190
  adapted_comment
181
191
  end
@@ -192,6 +202,7 @@ module CukeModeler
192
202
  adapted_step['keyword'] = step_ast[:keyword]
193
203
  adapted_step['name'] = step_ast[:text]
194
204
  adapted_step['line'] = step_ast[:location][:line]
205
+ adapted_step['column'] = step_ast[:location][:column]
195
206
 
196
207
  if step_ast[:doc_string]
197
208
  adapted_step['doc_string'] = adapt_doc_string(step_ast[:doc_string])
@@ -212,6 +223,7 @@ module CukeModeler
212
223
  adapted_doc_string['value'] = doc_string_ast[:content]
213
224
  adapted_doc_string['content_type'] = doc_string_ast[:media_type]
214
225
  adapted_doc_string['line'] = doc_string_ast[:location][:line]
226
+ adapted_doc_string['column'] = doc_string_ast[:location][:column]
215
227
 
216
228
  adapted_doc_string
217
229
  end
@@ -229,6 +241,7 @@ module CukeModeler
229
241
  adapted_step_table['rows'] << adapt_table_row(row)
230
242
  end
231
243
  adapted_step_table['line'] = step_table_ast[:location][:line]
244
+ adapted_step_table['column'] = step_table_ast[:location][:column]
232
245
 
233
246
  adapted_step_table
234
247
  end
@@ -242,6 +255,7 @@ module CukeModeler
242
255
  clear_child_elements(adapted_table_row, [[:cells]])
243
256
 
244
257
  adapted_table_row['line'] = table_row_ast[:location][:line]
258
+ adapted_table_row['column'] = table_row_ast[:location][:column]
245
259
 
246
260
  adapted_table_row['cells'] = []
247
261
  table_row_ast[:cells].each do |row|
@@ -260,6 +274,7 @@ module CukeModeler
260
274
 
261
275
  adapted_cell['value'] = cell_ast[:value]
262
276
  adapted_cell['line'] = cell_ast[:location][:line]
277
+ adapted_cell['column'] = cell_ast[:location][:column]
263
278
 
264
279
  adapted_cell
265
280
  end
@@ -322,10 +337,6 @@ module CukeModeler
322
337
  end
323
338
  end
324
339
 
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
340
  def clear_child_elements(ast, child_paths)
330
341
  child_paths.each do |traversal_path|
331
342
  # 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