cuke_modeler 3.9.0 → 3.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bac7201e203c0357c8137182d821bd7537968c2db97572dcc27e118ec3ccf489
4
- data.tar.gz: c08252bb8906a1648bb3f846bd1a17481316003bacc0526cbcfb2b321c9675c9
3
+ metadata.gz: b7e797a40be9122031fb1af313da9c05ded38167a525751135a27d711e901768
4
+ data.tar.gz: 6f793fedb5971b37d0733ca53d997b6f334c2e51716dff9b9c0cc2000ecc9c03
5
5
  SHA512:
6
- metadata.gz: 12647de1b642dbffff2c4a4567977c603dbbd138ce0ba465f0003ccf7455860e4fbf7abe82988da5878db2de6fbb8e4ac69541bca98005ecb9381fd40cc2d80e
7
- data.tar.gz: 6362c9a41314a6b66ac73ab8d11111e08947e0e3d6e4d7d4f43a593270947400242aa29ec82bf514ea93b4f4497f769bbb856117e8e74c1a9271eeb90837639b
6
+ metadata.gz: d1f6c8cbc8325af57aaae715afbfd12d96b279ae54a96ee0daedcb861f13fd10e662e0d350ef0139ab483c4423160844415fb7d0c7037c1e34e5fd498856a30f
7
+ data.tar.gz: 41100c94a4eaedc6de3ef4d57c0aa1ba93abd962c149d24d3852184bf34c83470a5ed381111918d3eefeb17eba290d2d08241722cacf54b43c4ed5aeba51f12c
data/CHANGELOG.md CHANGED
@@ -8,6 +8,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  Nothing yet...
10
10
 
11
+ ## [3.13.0] - 2021-09-25
12
+
13
+ ### Added
14
+ - Support added for more versions of the `cucumber-gherkin` gem
15
+ - 22.x
16
+
17
+ ## [3.12.0] - 2021-09-09
18
+
19
+ ### Added
20
+ - Support added for more versions of the `cucumber-gherkin` gem
21
+ - 21.x
22
+
23
+ ## [3.11.0] - 2021-07-31
24
+
25
+ ### Added
26
+ - Support added for more versions of the `cucumber-gherkin` gem
27
+ - 20.x
28
+
29
+ ### Fixed
30
+ - `Rule` models are now returnable from `Model#get_ancestor()`. Updating that method was missed when `Rule` models
31
+ were first added.
32
+
33
+ ## [3.10.0] - 2021-05-28
34
+
35
+ ### Added
36
+ - Support added for more versions of the `cucumber-gherkin` gem
37
+ - 19.x
38
+
39
+ ### Fixed
40
+ - `Rule` models now clear out parsing data for their tags. This data was an unintentional duplication of the
41
+ parsing data that the `Tag` models already contained.
42
+
11
43
 
12
44
  ## [3.9.0] - 2021-04-23
13
45
 
@@ -376,7 +408,11 @@ Nothing yet...
376
408
  - Initial release
377
409
 
378
410
 
379
- [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.9.0...HEAD
411
+ [Unreleased]: https://github.com/enkessler/cuke_modeler/compare/v3.13.0...HEAD
412
+ [3.13.0]: https://github.com/enkessler/cuke_modeler/compare/v3.12.0...v3.13.0
413
+ [3.12.0]: https://github.com/enkessler/cuke_modeler/compare/v3.11.0...v3.12.0
414
+ [3.11.0]: https://github.com/enkessler/cuke_modeler/compare/v3.10.0...v3.11.0
415
+ [3.10.0]: https://github.com/enkessler/cuke_modeler/compare/v3.9.0...v3.10.0
380
416
  [3.9.0]: https://github.com/enkessler/cuke_modeler/compare/v3.8.0...v3.9.0
381
417
  [3.8.0]: https://github.com/enkessler/cuke_modeler/compare/v3.7.0...v3.8.0
382
418
  [3.7.0]: https://github.com/enkessler/cuke_modeler/compare/v3.6.0...v3.7.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', '< 19.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
@@ -12,6 +12,8 @@ module CukeModeler
12
12
  def adapt_rule(rule_ast)
13
13
  adapted_rule = super(rule_ast)
14
14
 
15
+ clear_child_elements(adapted_rule, [[:rule, :tags]])
16
+
15
17
  # Tagging of Rules was added in Gherkin 18
16
18
  adapted_rule['tags'] = adapt_tags(rule_ast[:rule])
17
19
 
@@ -0,0 +1,61 @@
1
+ require_relative 'gherkin_18_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 19.x of the *cucumber-gherkin* gem into input that is consumable
8
+ # by this gem.
9
+ class Gherkin19Adapter < Gherkin18Adapter
10
+
11
+ # Adapts the AST sub-tree that is rooted at the given step node.
12
+ def adapt_step(step_ast)
13
+ adapted_step = super(step_ast)
14
+
15
+ clear_child_elements(adapted_step, [[:dataTable],
16
+ [:docString]])
17
+
18
+ if step_ast[:docString]
19
+ adapted_step['doc_string'] = adapt_doc_string(step_ast[:docString])
20
+ elsif step_ast[:dataTable]
21
+ adapted_step['table'] = adapt_step_table(step_ast[:dataTable])
22
+ end
23
+
24
+ adapted_step
25
+ end
26
+
27
+ # Adapts the AST sub-tree that is rooted at the given doc string node.
28
+ def adapt_doc_string(doc_string_ast)
29
+ adapted_doc_string = super(doc_string_ast)
30
+
31
+ adapted_doc_string['content_type'] = doc_string_ast[:mediaType]
32
+
33
+ adapted_doc_string
34
+ end
35
+
36
+ # Adapts the AST sub-tree that is rooted at the given example node.
37
+ def adapt_example(example_ast)
38
+ adapted_example = super(example_ast)
39
+
40
+ clear_child_elements(adapted_example, [[:tableHeader],
41
+ [:tableBody]])
42
+
43
+ adapted_example['rows'] << adapt_table_row(example_ast[:tableHeader]) if example_ast[:tableHeader]
44
+
45
+ example_ast[:tableBody].each do |row|
46
+ adapted_example['rows'] << adapt_table_row(row)
47
+ end
48
+
49
+ adapted_example
50
+ end
51
+
52
+
53
+ private
54
+
55
+
56
+ def test_has_examples?(ast_node)
57
+ ast_node[:scenario][:examples].any?
58
+ end
59
+
60
+ end
61
+ 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
@@ -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)
@@ -322,12 +324,9 @@ 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|
329
+ # Wipe the value if it's there but don't add any keys to the hash if it didn't already have them
331
330
  if ast['cuke_modeler_parsing_data'].dig(*traversal_path)
332
331
  bury(ast['cuke_modeler_parsing_data'], traversal_path, nil)
333
332
  end
@@ -346,11 +345,11 @@ module CukeModeler
346
345
  end
347
346
 
348
347
  def test_node?(ast_node)
349
- ast_node[:scenario]
348
+ !ast_node[:scenario].nil?
350
349
  end
351
350
 
352
351
  def test_has_examples?(ast_node)
353
- ast_node[:scenario][:examples]
352
+ !ast_node[:scenario][:examples].nil?
354
353
  end
355
354
 
356
355
  def test_uses_outline_keyword?(test_ast)
@@ -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
@@ -30,6 +30,7 @@ module CukeModeler
30
30
  directory: [Directory],
31
31
  feature_file: [FeatureFile],
32
32
  feature: [Feature],
33
+ rule: [Rule],
33
34
  test: [Scenario, Outline, Background],
34
35
  background: [Background],
35
36
  scenario: [Scenario],
@@ -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, 10, 11, 12, 13, 14, 15, 16, 17, 18]
12
+ supported_gherkin_versions = (9..22)
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
- @dialects ||= Gherkin::DIALECTS
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,40 @@ 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, 21, 22
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
83
+ when 19
84
+ # TODO: make these methods private?
85
+ # NOT A PART OF THE PUBLIC API
86
+ # The method to use for parsing Gherkin text
87
+ def parsing_method(source_text, filename)
88
+ messages = Gherkin.from_source(filename,
89
+ source_text,
90
+ { include_gherkin_document: true })
91
+ .to_a.map(&:to_hash)
92
+
93
+ error_message = messages.find { |message| message[:parseError] }
94
+ gherkin_ast_message = messages.find { |message| message[:gherkinDocument] }
95
+
96
+ raise error_message[:parseError][:message] if error_message
97
+
98
+ gherkin_ast_message[:gherkinDocument]
99
+ end
64
100
  when 13, 14, 15, 16, 17, 18
65
101
  # TODO: make these methods private?
66
102
  # NOT A PART OF THE PUBLIC API
@@ -158,3 +194,5 @@ module CukeModeler
158
194
 
159
195
  end
160
196
  end
197
+
198
+ # rubocop:enable Metrics/ModuleLength
@@ -1,4 +1,4 @@
1
1
  module CukeModeler
2
2
  # The gem version
3
- VERSION = '3.9.0'.freeze
3
+ VERSION = '3.13.0'.freeze
4
4
  end
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.9.0
4
+ version: 3.13.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-04-23 00:00:00.000000000 Z
11
+ date: 2021-09-25 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.0'
19
+ version: '23.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: '19.0'
26
+ version: '23.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.16.1
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.16.1
172
+ version: '1.0'
173
173
  - !ruby/object:Gem::Dependency
174
174
  name: test-unit
175
175
  requirement: !ruby/object:Gem::Requirement
@@ -225,7 +225,12 @@ files:
225
225
  - lib/cuke_modeler/adapters/gherkin_16_adapter.rb
226
226
  - lib/cuke_modeler/adapters/gherkin_17_adapter.rb
227
227
  - lib/cuke_modeler/adapters/gherkin_18_adapter.rb
228
+ - lib/cuke_modeler/adapters/gherkin_19_adapter.rb
229
+ - lib/cuke_modeler/adapters/gherkin_20_adapter.rb
230
+ - lib/cuke_modeler/adapters/gherkin_21_adapter.rb
231
+ - lib/cuke_modeler/adapters/gherkin_22_adapter.rb
228
232
  - lib/cuke_modeler/adapters/gherkin_9_adapter.rb
233
+ - lib/cuke_modeler/adapters/gherkin_base_adapter.rb
229
234
  - lib/cuke_modeler/containing.rb
230
235
  - lib/cuke_modeler/described.rb
231
236
  - lib/cuke_modeler/models/background.rb