cucumber 3.2.0 → 4.1.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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +192 -19
  3. data/CONTRIBUTING.md +2 -18
  4. data/README.md +4 -5
  5. data/bin/cucumber +1 -1
  6. data/lib/autotest/cucumber_mixin.rb +34 -39
  7. data/lib/cucumber/cli/configuration.rb +5 -5
  8. data/lib/cucumber/cli/main.rb +12 -12
  9. data/lib/cucumber/cli/options.rb +62 -71
  10. data/lib/cucumber/cli/profile_loader.rb +49 -26
  11. data/lib/cucumber/configuration.rb +31 -23
  12. data/lib/cucumber/constantize.rb +2 -5
  13. data/lib/cucumber/deprecate.rb +31 -7
  14. data/lib/cucumber/errors.rb +5 -7
  15. data/lib/cucumber/events/envelope.rb +9 -0
  16. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  17. data/lib/cucumber/events/hook_test_step_created.rb +13 -0
  18. data/lib/cucumber/events/step_activated.rb +2 -1
  19. data/lib/cucumber/events/test_case_created.rb +13 -0
  20. data/lib/cucumber/events/test_case_ready.rb +12 -0
  21. data/lib/cucumber/events/test_step_created.rb +13 -0
  22. data/lib/cucumber/events/undefined_parameter_type.rb +10 -0
  23. data/lib/cucumber/events.rb +13 -6
  24. data/lib/cucumber/file_specs.rb +6 -6
  25. data/lib/cucumber/filters/activate_steps.rb +5 -3
  26. data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
  27. data/lib/cucumber/filters/prepare_world.rb +5 -9
  28. data/lib/cucumber/filters/quit.rb +1 -3
  29. data/lib/cucumber/filters/tag_limits/verifier.rb +2 -4
  30. data/lib/cucumber/filters.rb +1 -0
  31. data/lib/cucumber/formatter/ansicolor.rb +40 -45
  32. data/lib/cucumber/formatter/ast_lookup.rb +165 -0
  33. data/lib/cucumber/formatter/backtrace_filter.rb +9 -8
  34. data/lib/cucumber/formatter/console.rb +58 -66
  35. data/lib/cucumber/formatter/console_counts.rb +4 -9
  36. data/lib/cucumber/formatter/console_issues.rb +6 -3
  37. data/lib/cucumber/formatter/duration.rb +1 -1
  38. data/lib/cucumber/formatter/duration_extractor.rb +3 -1
  39. data/lib/cucumber/formatter/errors.rb +6 -0
  40. data/lib/cucumber/formatter/fanout.rb +2 -0
  41. data/lib/cucumber/formatter/html.rb +11 -598
  42. data/lib/cucumber/formatter/http_io.rb +1 -1
  43. data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
  44. data/lib/cucumber/formatter/interceptor.rb +8 -28
  45. data/lib/cucumber/formatter/io.rb +1 -1
  46. data/lib/cucumber/formatter/json.rb +101 -115
  47. data/lib/cucumber/formatter/junit.rb +56 -56
  48. data/lib/cucumber/formatter/message.rb +22 -0
  49. data/lib/cucumber/formatter/message_builder.rb +255 -0
  50. data/lib/cucumber/formatter/pretty.rb +359 -153
  51. data/lib/cucumber/formatter/progress.rb +30 -32
  52. data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
  53. data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
  54. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
  55. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
  56. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
  57. data/lib/cucumber/formatter/rerun.rb +22 -4
  58. data/lib/cucumber/formatter/stepdefs.rb +1 -2
  59. data/lib/cucumber/formatter/steps.rb +2 -3
  60. data/lib/cucumber/formatter/summary.rb +16 -8
  61. data/lib/cucumber/formatter/unicode.rb +15 -17
  62. data/lib/cucumber/formatter/usage.rb +11 -10
  63. data/lib/cucumber/gherkin/data_table_parser.rb +17 -6
  64. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
  65. data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
  66. data/lib/cucumber/gherkin/steps_parser.rb +17 -8
  67. data/lib/cucumber/glue/dsl.rb +1 -1
  68. data/lib/cucumber/glue/hook.rb +34 -11
  69. data/lib/cucumber/glue/invoke_in_world.rb +13 -18
  70. data/lib/cucumber/glue/proto_world.rb +42 -33
  71. data/lib/cucumber/glue/registry_and_more.rb +42 -12
  72. data/lib/cucumber/glue/snippet.rb +23 -22
  73. data/lib/cucumber/glue/step_definition.rb +42 -19
  74. data/lib/cucumber/glue/world_factory.rb +1 -1
  75. data/lib/cucumber/hooks.rb +11 -11
  76. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +1 -1
  77. data/lib/cucumber/multiline_argument/data_table.rb +97 -64
  78. data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
  79. data/lib/cucumber/multiline_argument.rb +4 -6
  80. data/lib/cucumber/platform.rb +3 -3
  81. data/lib/cucumber/rake/task.rb +16 -16
  82. data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
  83. data/lib/cucumber/running_test_case.rb +2 -53
  84. data/lib/cucumber/runtime/after_hooks.rb +8 -4
  85. data/lib/cucumber/runtime/before_hooks.rb +8 -4
  86. data/lib/cucumber/runtime/for_programming_languages.rb +4 -2
  87. data/lib/cucumber/runtime/step_hooks.rb +6 -2
  88. data/lib/cucumber/runtime/support_code.rb +13 -15
  89. data/lib/cucumber/runtime/user_interface.rb +6 -16
  90. data/lib/cucumber/runtime.rb +34 -58
  91. data/lib/cucumber/step_definition_light.rb +4 -3
  92. data/lib/cucumber/step_definitions.rb +2 -2
  93. data/lib/cucumber/step_match.rb +12 -11
  94. data/lib/cucumber/step_match_search.rb +2 -1
  95. data/lib/cucumber/term/ansicolor.rb +9 -9
  96. data/lib/cucumber/version +1 -1
  97. data/lib/cucumber.rb +1 -1
  98. metadata +251 -81
  99. data/lib/cucumber/formatter/cucumber.css +0 -286
  100. data/lib/cucumber/formatter/cucumber.sass +0 -247
  101. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
  102. data/lib/cucumber/formatter/html_builder.rb +0 -121
  103. data/lib/cucumber/formatter/inline-js.js +0 -30
  104. data/lib/cucumber/formatter/jquery-min.js +0 -154
  105. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  106. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
  107. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
  108. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  109. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  110. data/lib/cucumber/step_argument.rb +0 -25
@@ -1,394 +0,0 @@
1
- # frozen_string_literal: true
2
- module Cucumber
3
- module Formatter
4
- module LegacyApi
5
- # Adapters to pass to the legacy API formatters that provide the interface
6
- # of the old AST classes
7
- module Ast
8
-
9
- # Acts as a null object, or a base class
10
- class Node
11
- def initialize(node = nil)
12
- @node = node
13
- end
14
-
15
- def accept(formatter)
16
- end
17
-
18
- attr_reader :node
19
- private :node
20
- end
21
-
22
- # Null object for HeaderRow language.
23
- # ExampleTableRow#keyword is never called on them,
24
- # but this will pass silently if it happens anyway
25
- class NullLanguage
26
- def method_missing(*_args, &_block)
27
- self
28
- end
29
-
30
- def to_ary
31
- ['']
32
- end
33
- end
34
-
35
- class HookResultCollection
36
- def initialize
37
- @children = []
38
- end
39
-
40
- def accept(formatter)
41
- @children.each { |child| child.accept(formatter) }
42
- end
43
-
44
- def send_output_to(formatter)
45
- @children.each { |child| child.send_output_to(formatter) }
46
- end
47
-
48
- def describe_exception_to(formatter)
49
- @children.each { |child| child.describe_exception_to(formatter) }
50
- end
51
-
52
- def <<(child)
53
- @children << child
54
- end
55
- end
56
-
57
- Comments = Struct.new(:comments) do
58
- def accept(formatter)
59
- return if comments.empty?
60
- formatter.before_comment comments
61
- comments.each do |comment|
62
- formatter.comment_line comment.to_s.strip
63
- end
64
- formatter.after_comment comments
65
- end
66
- end
67
-
68
- class HookResult
69
- def initialize(result, messages, embeddings)
70
- @result, @messages, @embeddings = result, messages, embeddings
71
- @already_accepted = false
72
- end
73
-
74
- def accept(formatter)
75
- unless @already_accepted
76
- send_output_to(formatter)
77
- describe_exception_to(formatter)
78
- end
79
- self
80
- end
81
-
82
- def send_output_to(formatter)
83
- return if @already_accepted
84
- @messages.each { |message| formatter.puts(message) }
85
- @embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
86
- end
87
-
88
- def describe_exception_to(formatter)
89
- return if @already_accepted
90
- @result.describe_exception_to(formatter)
91
- @already_accepted = true
92
- end
93
- end
94
-
95
- StepInvocation = Struct.new(:step_match,
96
- :status,
97
- :duration,
98
- :exception,
99
- :indent,
100
- :background,
101
- :step,
102
- :messages,
103
- :embeddings) do
104
- extend Forwardable
105
-
106
- def_delegators :step, :keyword, :text, :multiline_arg, :location
107
-
108
- def accept(formatter)
109
- formatter.before_step(self)
110
- Ast::Comments.new(step.comments).accept(formatter)
111
- messages.each { |message| formatter.puts(message) }
112
- embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
113
- formatter.before_step_result(*step_result_attributes)
114
- print_step_name(formatter)
115
- Ast::MultilineArg.for(multiline_arg).accept(formatter)
116
- print_exception(formatter)
117
- formatter.after_step_result(*step_result_attributes)
118
- formatter.after_step(self)
119
- end
120
-
121
- def step_result_attributes
122
- legacy_multiline_arg = if multiline_arg.is_a?(Core::Ast::EmptyMultilineArgument)
123
- nil
124
- else
125
- step.multiline_arg
126
- end
127
- [keyword, step_match, legacy_multiline_arg, status, exception, source_indent, background, file_colon_line]
128
- end
129
-
130
- def failed?
131
- status != :passed
132
- end
133
-
134
- def passed?
135
- status == :passed
136
- end
137
-
138
- def dom_id
139
-
140
- end
141
-
142
- def actual_keyword(previous_step_keyword = nil)
143
- step.actual_keyword(previous_step_keyword)
144
- end
145
-
146
- def file_colon_line
147
- location.to_s
148
- end
149
-
150
- def backtrace_line
151
- step_match.backtrace_line
152
- end
153
-
154
- def step_invocation
155
- self
156
- end
157
-
158
- def to_s
159
- text
160
- end
161
-
162
- private
163
-
164
- def source_indent
165
- indent.of(self)
166
- end
167
-
168
- def print_step_name(formatter)
169
- formatter.step_name(
170
- keyword,
171
- step_match,
172
- status,
173
- source_indent,
174
- background,
175
- location.to_s)
176
- end
177
-
178
- def print_exception(formatter)
179
- return unless exception
180
- raise exception if ENV['FAIL_FAST']
181
- formatter.exception(exception, status)
182
- end
183
- end
184
-
185
- class StepInvocations < Array
186
- def failed?
187
- any?(&:failed?)
188
- end
189
-
190
- def passed?
191
- all?(&:passed?)
192
- end
193
-
194
- def status
195
- return :passed if passed?
196
- failed_step.status
197
- end
198
-
199
- def exception
200
- failed_step.exception if failed_step
201
- end
202
-
203
- private
204
-
205
- def failed_step
206
- detect(&:failed?)
207
- end
208
- end
209
-
210
- class DataTableRow
211
- def initialize(row, line)
212
- @values = row
213
- @line = line
214
- end
215
-
216
- def dom_id
217
- "row_#{line}"
218
- end
219
-
220
- def accept(formatter)
221
- formatter.before_table_row(self)
222
- values.each do |value|
223
- formatter.before_table_cell(value)
224
- formatter.table_cell_value(value, status)
225
- formatter.after_table_cell(value)
226
- end
227
- formatter.after_table_row(self)
228
- end
229
-
230
- def status
231
- :skipped
232
- end
233
-
234
- def exception
235
- nil
236
- end
237
-
238
- attr_reader :values, :line
239
- private :values, :line
240
- end
241
-
242
- ExampleTableRow = Struct.new(:exception, :status, :cells, :location, :language) do
243
- def name
244
- '| ' + cells.join(' | ') + ' |'
245
- end
246
-
247
- def to_s
248
- name
249
- end
250
-
251
- def failed?
252
- status == :failed
253
- end
254
-
255
- def line
256
- location.line
257
- end
258
-
259
- def keyword
260
- # This method is only called when used for the scenario name line with
261
- # the expand option, and on that line the keyword is "Scenario"
262
- language.scenario_keywords[0]
263
- end
264
- end
265
-
266
- class LegacyTableRow < DataTableRow
267
- def accept(formatter)
268
- formatter.before_table_row(self)
269
- values.each do |value|
270
- formatter.before_table_cell(value.value)
271
- formatter.table_cell_value(value.value, value.status)
272
- formatter.after_table_cell(value.value)
273
- end
274
- formatter.after_table_row(self)
275
- end
276
- end
277
-
278
- Tags = Struct.new(:tags) do
279
- def accept(formatter)
280
- formatter.before_tags tags
281
- tags.each do |tag|
282
- formatter.tag_name tag.name
283
- end
284
- formatter.after_tags tags
285
- end
286
- end
287
-
288
- Scenario = Struct.new(:status, :name, :location) do
289
- def backtrace_line(step_name = name.to_s, line = self.location.line)
290
- "#{location.on_line(line)}:in `#{step_name}'"
291
- end
292
-
293
- def failed?
294
- :failed == status
295
- end
296
-
297
- def line
298
- location.line
299
- end
300
- end
301
-
302
- ScenarioOutline = Struct.new(:status, :name, :location) do
303
- def backtrace_line(step_name = name.to_s, line = self.location.line)
304
- "#{location.on_line(line)}:in `#{step_name}'"
305
- end
306
-
307
- def failed?
308
- :failed == status
309
- end
310
-
311
- def line
312
- location.line
313
- end
314
- end
315
-
316
- module MultilineArg
317
- class << self
318
- def for(node)
319
- Builder.new(node).result
320
- end
321
- end
322
-
323
- class Builder
324
- def initialize(node)
325
- node.describe_to(self)
326
- end
327
-
328
- def doc_string(node)
329
- @result = DocString.new(node)
330
- end
331
-
332
- def data_table(node)
333
- @result = DataTable.new(node)
334
- end
335
-
336
- def legacy_table(node)
337
- @result = LegacyTable.new(node)
338
- end
339
-
340
- def result
341
- @result || Node.new(nil)
342
- end
343
- end
344
-
345
- class DocString < Node
346
- def accept(formatter)
347
- formatter.before_multiline_arg node
348
- formatter.doc_string(node)
349
- formatter.after_multiline_arg node
350
- end
351
- end
352
-
353
- class DataTable < Cucumber::MultilineArgument::DataTable
354
- def node
355
- @ast_table
356
- end
357
-
358
- def accept(formatter)
359
- formatter.before_multiline_arg self
360
- node.raw.each_with_index do |row, index|
361
- line = node.location.line + index
362
- DataTableRow.new(row, line).accept(formatter)
363
- end
364
- formatter.after_multiline_arg self
365
- end
366
- end
367
- end
368
-
369
- class LegacyTable < SimpleDelegator
370
- def accept(formatter)
371
- formatter.before_multiline_arg self
372
- cells_rows.each_with_index do |row, index|
373
- line = location.line + index
374
- LegacyTableRow.new(row, line).accept(formatter)
375
- end
376
- formatter.after_multiline_arg self
377
- end
378
- end
379
-
380
- Features = Struct.new(:duration)
381
-
382
- class Background < SimpleDelegator
383
- def initialize(feature, node)
384
- super node
385
- @feature = feature
386
- end
387
-
388
- attr_reader :feature
389
- end
390
-
391
- end
392
- end
393
- end
394
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
- module Cucumber
3
- module Formatter
4
- module LegacyApi
5
-
6
- class Results
7
- def initialize
8
- # Optimization - quicker lookup.
9
- @inserted_steps = {}
10
- @inserted_scenarios = {}
11
- end
12
-
13
- def step_visited(step) #:nodoc:
14
- step_id = step.object_id
15
-
16
- return if @inserted_steps.key?(step_id)
17
- @inserted_steps[step_id] = step
18
- steps.push(step)
19
- end
20
-
21
- def scenario_visited(scenario) #:nodoc:
22
- scenario_id = scenario.object_id
23
-
24
- return if @inserted_scenarios.key?(scenario_id)
25
- @inserted_scenarios[scenario_id] = scenario
26
- scenarios.push(scenario)
27
- end
28
-
29
- def steps(status = nil) #:nodoc:
30
- @steps ||= []
31
- if(status)
32
- @steps.select{|step| step.status == status}
33
- else
34
- @steps
35
- end
36
- end
37
-
38
- def scenarios(status = nil) #:nodoc:
39
- @scenarios ||= []
40
- if(status)
41
- @scenarios.select{|scenario| scenario.status == status}
42
- else
43
- @scenarios
44
- end
45
- end
46
- end
47
-
48
- end
49
- end
50
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'cucumber/gherkin/i18n'
3
-
4
- module Cucumber
5
- module Formatter
6
- module LegacyApi
7
-
8
- # This is what's passed to the constructor of the formatters
9
- class RuntimeFacade < Struct.new(:results, :support_code, :configuration)
10
- def unmatched_step_definitions
11
- support_code.unmatched_step_definitions
12
- end
13
-
14
- def snippet_text(step_keyword, step_name, multiline_arg) #:nodoc:
15
- keyword = Cucumber::Gherkin::I18n.code_keyword_for(step_keyword).strip
16
- configuration.snippet_generators.map { |generator|
17
- generator.call(keyword, step_name, multiline_arg, configuration.snippet_type)
18
- }.join("\n")
19
- end
20
-
21
- def scenarios(status = nil)
22
- results.scenarios(status)
23
- end
24
-
25
- def steps(status = nil)
26
- results.steps(status)
27
- end
28
- end
29
-
30
- end
31
- end
32
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cucumber
4
- # Defines the location and value of a captured argument from the step
5
- # text
6
- class StepArgument
7
- def self.arguments_from(regexp, step_name)
8
- match = regexp.match(step_name)
9
- if match
10
- n = 0
11
- match.captures.map do |val|
12
- n += 1
13
- offset = match.offset(n)[0]
14
- new(offset, val)
15
- end
16
- end
17
- end
18
-
19
- attr_reader :offset, :val
20
-
21
- def initialize(offset, val)
22
- @offset, @val = offset, val
23
- end
24
- end
25
- end