cucumber-core 3.2.1 → 4.0.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 (33) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +52 -0
  3. data/lib/cucumber/core/compiler.rb +37 -145
  4. data/lib/cucumber/core/events.rb +1 -4
  5. data/lib/cucumber/core/gherkin/parser.rb +14 -22
  6. data/lib/cucumber/core/report/summary.rb +1 -23
  7. data/lib/cucumber/core/test/action.rb +2 -2
  8. data/lib/cucumber/core/test/around_hook.rb +4 -0
  9. data/lib/cucumber/core/test/case.rb +15 -121
  10. data/lib/cucumber/core/{ast → test}/data_table.rb +6 -8
  11. data/lib/cucumber/core/{ast → test}/doc_string.rb +5 -9
  12. data/lib/cucumber/core/{ast → test}/empty_multiline_argument.rb +1 -2
  13. data/lib/cucumber/core/test/filters/locations_filter.rb +2 -2
  14. data/lib/cucumber/core/{ast → test}/location.rb +10 -17
  15. data/lib/cucumber/core/test/runner.rb +5 -3
  16. data/lib/cucumber/core/test/step.rb +20 -36
  17. data/lib/cucumber/core/{ast → test}/tag.rb +1 -1
  18. data/lib/cucumber/core/version.rb +1 -1
  19. metadata +12 -26
  20. data/lib/cucumber/core/ast.rb +0 -14
  21. data/lib/cucumber/core/ast/background.rb +0 -41
  22. data/lib/cucumber/core/ast/comment.rb +0 -28
  23. data/lib/cucumber/core/ast/describes_itself.rb +0 -21
  24. data/lib/cucumber/core/ast/empty_background.rb +0 -17
  25. data/lib/cucumber/core/ast/examples_table.rb +0 -119
  26. data/lib/cucumber/core/ast/feature.rb +0 -88
  27. data/lib/cucumber/core/ast/names.rb +0 -25
  28. data/lib/cucumber/core/ast/outline_step.rb +0 -53
  29. data/lib/cucumber/core/ast/scenario.rb +0 -42
  30. data/lib/cucumber/core/ast/scenario_outline.rb +0 -45
  31. data/lib/cucumber/core/ast/step.rb +0 -83
  32. data/lib/cucumber/core/gherkin/ast_builder.rb +0 -403
  33. data/lib/cucumber/core/gherkin/tag_expression.rb +0 -65
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'cucumber/core/ast/describes_itself'
3
- require 'cucumber/core/ast/location'
4
-
5
- module Cucumber
6
- module Core
7
- module Ast
8
- class Step
9
- include HasLocation
10
- include DescribesItself
11
-
12
- attr_reader :keyword, :text, :language, :comments, :exception, :multiline_arg
13
-
14
- def initialize(language, location, comments, keyword, text, multiline_arg)
15
- @language, @location, @comments, @keyword, @text, @multiline_arg = language, location, comments, keyword, text, multiline_arg
16
- end
17
-
18
- def to_s
19
- text
20
- end
21
-
22
- def backtrace_line
23
- "#{location}:in `#{keyword}#{text}'"
24
- end
25
-
26
- def actual_keyword(previous_step_keyword = nil)
27
- if [language.and_keywords, language.but_keywords].flatten.uniq.include? keyword
28
- if previous_step_keyword.nil?
29
- language.given_keywords.reject{|kw| kw == '* '}[0]
30
- else
31
- previous_step_keyword
32
- end
33
- else
34
- keyword
35
- end
36
- end
37
-
38
- def original_location
39
- location
40
- end
41
-
42
- def inspect
43
- keyword_and_text = [keyword, text].join(": ")
44
- %{#<#{self.class} "#{keyword_and_text}" (#{location})>}
45
- end
46
-
47
-
48
- private
49
-
50
- def children
51
- [@multiline_arg]
52
- end
53
-
54
- def description_for_visitors
55
- :step
56
- end
57
- end
58
-
59
- class ExpandedOutlineStep < Step
60
-
61
- def initialize(outline_step, language, location, comments, keyword, text, multiline_arg)
62
- @outline_step, @language, @location, @comments, @keyword, @text, @multiline_arg = outline_step, language, location, comments, keyword, text, multiline_arg
63
- end
64
-
65
- def all_locations
66
- @outline_step.all_locations
67
- end
68
-
69
- def original_location
70
- @outline_step.location
71
- end
72
-
73
- alias :step_backtrace_line :backtrace_line
74
-
75
- def backtrace_line
76
- "#{step_backtrace_line}\n" +
77
- "#{@outline_step.location}:in `#{@outline_step.keyword}#{@outline_step.text}'"
78
- end
79
-
80
- end
81
- end
82
- end
83
- end
@@ -1,403 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'cucumber/core/ast'
3
- require 'cucumber/core/platform'
4
-
5
- module Cucumber
6
- module Core
7
- module Gherkin
8
- # Builds an AST of a feature by listening to events from the
9
- # Gherkin parser.
10
- class AstBuilder
11
-
12
- def initialize(uri)
13
- @uri = uri
14
- end
15
-
16
- def feature(attributes)
17
- DocumentBuilder.new(file, attributes).feature
18
- end
19
-
20
- private
21
-
22
- def file
23
- @uri
24
- end
25
-
26
- class Builder
27
- attr_reader :file, :attributes, :comments, :line
28
- private :file, :attributes, :comments, :line
29
-
30
- def initialize(file, attributes)
31
- @file = file
32
- @attributes = rubify_keys(attributes.dup)
33
- @comments = []
34
- @line = @attributes[:location][:line]
35
- end
36
-
37
- def handle_comments(comments)
38
- remaining_comments = []
39
- comments.each do |comment|
40
- if line > comment.location.line
41
- @comments << comment
42
- else
43
- remaining_comments << comment
44
- end
45
- end
46
- children.each { |child| remaining_comments = child.handle_comments(remaining_comments) }
47
- remaining_comments
48
- end
49
-
50
- private
51
-
52
- def keyword
53
- attributes[:keyword]
54
- end
55
-
56
- def name
57
- attributes[:name]
58
- end
59
-
60
- def description
61
- attributes[:description] ||= ""
62
- end
63
-
64
- def tags
65
- attributes[:tags].map do |tag|
66
- Ast::Tag.new(
67
- Ast::Location.new(file, tag[:location][:line]),
68
- tag[:name])
69
- end
70
- end
71
-
72
- def location
73
- Ast::Location.new(file, attributes[:location][:line])
74
- end
75
-
76
- def children
77
- []
78
- end
79
-
80
- def rubify_keys(hash)
81
- hash.keys.each do |key|
82
- if key.downcase != key
83
- hash[underscore(key).to_sym] = hash.delete(key)
84
- end
85
- end
86
- return hash
87
- end
88
-
89
- def underscore(string)
90
- string.to_s.gsub(/::/, '/').
91
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
92
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
93
- tr("-", "_").
94
- downcase
95
- end
96
- end
97
-
98
- class DocumentBuilder < Builder
99
- def initialize(file, attributes)
100
- @file = file
101
- @attributes = rubify_keys(attributes.dup)
102
- end
103
-
104
- def feature
105
- return Ast::NullFeature.new unless attributes[:feature]
106
- feature_builder = FeatureBuilder.new(file, attributes[:feature])
107
- feature_builder.handle_comments(all_comments)
108
- feature_builder.result
109
- end
110
-
111
- def all_comments
112
- attributes[:comments].map do |comment|
113
- Ast::Comment.new(
114
- Ast::Location.new(file, comment[:location][:line]),
115
- comment[:text]
116
- )
117
- end
118
- end
119
- end
120
-
121
- class FeatureBuilder < Builder
122
- attr_reader :language, :feature_element_builders
123
-
124
- def initialize(*)
125
- super
126
- @language = Ast::LanguageDelegator.new(attributes[:language], ::Gherkin::Dialect.for(attributes[:language]))
127
- @feature_element_builders = attributes[:children].map do |child|
128
- case child[:type]
129
- when :Background
130
- BackgroundBuilder.new(file, child)
131
- when :Scenario
132
- ScenarioBuilder.new(file, child)
133
- else
134
- ScenarioOutlineBuilder.new(file, child)
135
- end
136
- end
137
- end
138
-
139
- def result
140
- Ast::Feature.new(
141
- language,
142
- location,
143
- comments,
144
- tags,
145
- keyword,
146
- name,
147
- description,
148
- feature_elements
149
- )
150
- end
151
-
152
- private
153
-
154
- def feature_elements
155
- feature_element_builders.map { |builder| builder.result(language) }
156
- end
157
-
158
- def children
159
- feature_element_builders
160
- end
161
- end
162
-
163
- class BackgroundBuilder < Builder
164
- attr_reader :step_builders
165
-
166
- def initialize(*)
167
- super
168
- @step_builders = attributes[:steps].map { |step| StepBuilder.new(file, step) }
169
- end
170
-
171
- def result(language)
172
- Ast::Background.new(
173
- location,
174
- comments,
175
- keyword,
176
- name,
177
- description,
178
- steps(language)
179
- )
180
- end
181
-
182
- def steps(language)
183
- step_builders.map { |builder| builder.result(language) }
184
- end
185
-
186
- def children
187
- step_builders
188
- end
189
- end
190
-
191
- class ScenarioBuilder < Builder
192
- attr_reader :step_builders
193
-
194
- def initialize(*)
195
- super
196
- @step_builders = attributes[:steps].map { |step| StepBuilder.new(file, step) }
197
- end
198
-
199
- def result(language)
200
- Ast::Scenario.new(
201
- location,
202
- comments,
203
- tags,
204
- keyword,
205
- name,
206
- description,
207
- steps(language)
208
- )
209
- end
210
-
211
- def steps(language)
212
- step_builders.map { |builder| builder.result(language) }
213
- end
214
-
215
- def children
216
- step_builders
217
- end
218
- end
219
-
220
- class StepBuilder < Builder
221
- attr_reader :multiline_argument_builder
222
-
223
- def initialize(*)
224
- super
225
- @multiline_argument_builder = attributes[:argument] ? argument_builder(attributes[:argument]) : nil
226
- end
227
-
228
- def result(language)
229
- Ast::Step.new(
230
- language,
231
- location,
232
- comments,
233
- keyword,
234
- attributes[:text],
235
- multiline_argument
236
- )
237
- end
238
-
239
- def multiline_argument
240
- return Ast::EmptyMultilineArgument.new unless multiline_argument_builder
241
- multiline_argument_builder.result
242
- end
243
-
244
- def children
245
- return [] unless multiline_argument_builder
246
- [multiline_argument_builder]
247
- end
248
-
249
- private
250
-
251
- def argument_builder(attributes)
252
- attributes[:type] == :DataTable ? DataTableBuilder.new(file, attributes) : DocStringBuilder.new(file, attributes)
253
- end
254
- end
255
-
256
- class OutlineStepBuilder < StepBuilder
257
- def result(language)
258
- Ast::OutlineStep.new(
259
- language,
260
- location,
261
- comments,
262
- keyword,
263
- attributes[:text],
264
- multiline_argument
265
- )
266
- end
267
- end
268
-
269
- class ScenarioOutlineBuilder < Builder
270
- attr_reader :step_builders, :example_builders
271
-
272
- def initialize(*)
273
- super
274
- @step_builders = attributes[:steps].map { |step| OutlineStepBuilder.new(file, step) }
275
- @example_builders = attributes[:examples] ? attributes[:examples].map { |example| ExamplesTableBuilder.new(file, example) } : []
276
- end
277
-
278
- def result(language)
279
- Ast::ScenarioOutline.new(
280
- location,
281
- comments,
282
- tags,
283
- keyword,
284
- name,
285
- description,
286
- steps(language),
287
- examples(language)
288
- )
289
- end
290
-
291
- def steps(language)
292
- step_builders.map { |builder| builder.result(language) }
293
- end
294
-
295
- def examples(language)
296
- example_builders.map { |builder| builder.result(language) }
297
- end
298
-
299
- def children
300
- step_builders + example_builders
301
- end
302
- end
303
-
304
- class ExamplesTableBuilder < Builder
305
- attr_reader :header_builder, :example_rows_builders
306
-
307
- def initialize(*)
308
- super
309
- @header_builder = attributes[:table_header] ? HeaderBuilder.new(file, attributes[:table_header]) : NullHeaderBuilder.new
310
- @example_rows_builders = attributes[:table_body] ? attributes[:table_body].map { |row_attributes| ExampleRowBuilder.new(file, row_attributes) } : []
311
- end
312
-
313
- def result(language)
314
- Ast::Examples.new(
315
- location,
316
- comments,
317
- tags,
318
- keyword,
319
- name,
320
- description,
321
- header,
322
- example_rows(language)
323
- )
324
- end
325
-
326
- private
327
-
328
- def header
329
- @header = header_builder.result
330
- end
331
-
332
- def example_rows(language)
333
- example_rows_builders.each.with_index.map { |builder, index| builder.result(language, header, index) }
334
- end
335
-
336
- class HeaderBuilder < Builder
337
- def result
338
- cells = attributes[:cells].map { |c| c[:value] }
339
- Ast::ExamplesTable::Header.new(cells, location, comments)
340
- end
341
- end
342
-
343
- class NullHeaderBuilder < Builder
344
- def initialize
345
- @line = -1 # this inhibits Builder#handle_comments to put any comments in this object.
346
- end
347
-
348
- def result
349
- nil
350
- end
351
- end
352
-
353
- def children
354
- [header_builder] + example_rows_builders
355
- end
356
-
357
- class ExampleRowBuilder < Builder
358
- def result(language, header, index)
359
- cells = attributes[:cells].map { |c| c[:value] }
360
- header.build_row(cells, index + 1, location, language, comments)
361
- end
362
- end
363
- end
364
-
365
- class DataTableBuilder < Builder
366
- def result
367
- Ast::DataTable.new(
368
- rows,
369
- location
370
- )
371
- end
372
-
373
- def rows
374
- attributes[:rows] = attributes[:rows].map { |r| r[:cells].map { |c| c[:value] } }
375
- end
376
-
377
- def location
378
- first_line = attributes[:location][:line]
379
- last_line = first_line + attributes[:rows].length - 1
380
- Ast::Location.new(file, first_line..last_line)
381
- end
382
- end
383
-
384
- class DocStringBuilder < Builder
385
- def result
386
- Ast::DocString.new(
387
- attributes[:content],
388
- attributes[:content_type],
389
- doc_string_location
390
- )
391
- end
392
-
393
- def doc_string_location
394
- start_line = attributes[:location][:line]
395
- end_line = start_line + attributes[:content].each_line.to_a.length + 1
396
- Ast::Location.new(file, start_line..end_line)
397
- end
398
- end
399
-
400
- end
401
- end
402
- end
403
- end