cucumber-core 3.2.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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