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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +192 -19
- data/CONTRIBUTING.md +2 -18
- data/README.md +4 -5
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +34 -39
- data/lib/cucumber/cli/configuration.rb +5 -5
- data/lib/cucumber/cli/main.rb +12 -12
- data/lib/cucumber/cli/options.rb +62 -71
- data/lib/cucumber/cli/profile_loader.rb +49 -26
- data/lib/cucumber/configuration.rb +31 -23
- data/lib/cucumber/constantize.rb +2 -5
- data/lib/cucumber/deprecate.rb +31 -7
- data/lib/cucumber/errors.rb +5 -7
- data/lib/cucumber/events/envelope.rb +9 -0
- data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
- data/lib/cucumber/events/hook_test_step_created.rb +13 -0
- data/lib/cucumber/events/step_activated.rb +2 -1
- data/lib/cucumber/events/test_case_created.rb +13 -0
- data/lib/cucumber/events/test_case_ready.rb +12 -0
- data/lib/cucumber/events/test_step_created.rb +13 -0
- data/lib/cucumber/events/undefined_parameter_type.rb +10 -0
- data/lib/cucumber/events.rb +13 -6
- data/lib/cucumber/file_specs.rb +6 -6
- data/lib/cucumber/filters/activate_steps.rb +5 -3
- data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
- data/lib/cucumber/filters/prepare_world.rb +5 -9
- data/lib/cucumber/filters/quit.rb +1 -3
- data/lib/cucumber/filters/tag_limits/verifier.rb +2 -4
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/formatter/ansicolor.rb +40 -45
- data/lib/cucumber/formatter/ast_lookup.rb +165 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +9 -8
- data/lib/cucumber/formatter/console.rb +58 -66
- data/lib/cucumber/formatter/console_counts.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +6 -3
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/duration_extractor.rb +3 -1
- data/lib/cucumber/formatter/errors.rb +6 -0
- data/lib/cucumber/formatter/fanout.rb +2 -0
- data/lib/cucumber/formatter/html.rb +11 -598
- data/lib/cucumber/formatter/http_io.rb +1 -1
- data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
- data/lib/cucumber/formatter/interceptor.rb +8 -28
- data/lib/cucumber/formatter/io.rb +1 -1
- data/lib/cucumber/formatter/json.rb +101 -115
- data/lib/cucumber/formatter/junit.rb +56 -56
- data/lib/cucumber/formatter/message.rb +22 -0
- data/lib/cucumber/formatter/message_builder.rb +255 -0
- data/lib/cucumber/formatter/pretty.rb +359 -153
- data/lib/cucumber/formatter/progress.rb +30 -32
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
- data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
- data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
- data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
- data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
- data/lib/cucumber/formatter/rerun.rb +22 -4
- data/lib/cucumber/formatter/stepdefs.rb +1 -2
- data/lib/cucumber/formatter/steps.rb +2 -3
- data/lib/cucumber/formatter/summary.rb +16 -8
- data/lib/cucumber/formatter/unicode.rb +15 -17
- data/lib/cucumber/formatter/usage.rb +11 -10
- data/lib/cucumber/gherkin/data_table_parser.rb +17 -6
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
- data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
- data/lib/cucumber/gherkin/steps_parser.rb +17 -8
- data/lib/cucumber/glue/dsl.rb +1 -1
- data/lib/cucumber/glue/hook.rb +34 -11
- data/lib/cucumber/glue/invoke_in_world.rb +13 -18
- data/lib/cucumber/glue/proto_world.rb +42 -33
- data/lib/cucumber/glue/registry_and_more.rb +42 -12
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +42 -19
- data/lib/cucumber/glue/world_factory.rb +1 -1
- data/lib/cucumber/hooks.rb +11 -11
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +1 -1
- data/lib/cucumber/multiline_argument/data_table.rb +97 -64
- data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
- data/lib/cucumber/multiline_argument.rb +4 -6
- data/lib/cucumber/platform.rb +3 -3
- data/lib/cucumber/rake/task.rb +16 -16
- data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
- data/lib/cucumber/running_test_case.rb +2 -53
- data/lib/cucumber/runtime/after_hooks.rb +8 -4
- data/lib/cucumber/runtime/before_hooks.rb +8 -4
- data/lib/cucumber/runtime/for_programming_languages.rb +4 -2
- data/lib/cucumber/runtime/step_hooks.rb +6 -2
- data/lib/cucumber/runtime/support_code.rb +13 -15
- data/lib/cucumber/runtime/user_interface.rb +6 -16
- data/lib/cucumber/runtime.rb +34 -58
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +12 -11
- data/lib/cucumber/step_match_search.rb +2 -1
- data/lib/cucumber/term/ansicolor.rb +9 -9
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +1 -1
- metadata +251 -81
- data/lib/cucumber/formatter/cucumber.css +0 -286
- data/lib/cucumber/formatter/cucumber.sass +0 -247
- data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
- data/lib/cucumber/formatter/html_builder.rb +0 -121
- data/lib/cucumber/formatter/inline-js.js +0 -30
- data/lib/cucumber/formatter/jquery-min.js +0 -154
- data/lib/cucumber/formatter/json_pretty.rb +0 -11
- data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
- data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
- data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
- data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
- data/lib/cucumber/step_argument.rb +0 -25
@@ -1,1028 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'forwardable'
|
3
|
-
require 'delegate'
|
4
|
-
require 'cucumber/errors'
|
5
|
-
require 'cucumber/multiline_argument'
|
6
|
-
require 'cucumber/formatter/backtrace_filter'
|
7
|
-
require 'cucumber/formatter/legacy_api/ast'
|
8
|
-
|
9
|
-
module Cucumber
|
10
|
-
module Formatter
|
11
|
-
module LegacyApi
|
12
|
-
|
13
|
-
Adapter = Struct.new(:formatter, :results, :config) do
|
14
|
-
extend Forwardable
|
15
|
-
|
16
|
-
def initialize(*)
|
17
|
-
super
|
18
|
-
emit_deprecation_warning
|
19
|
-
|
20
|
-
@matches = collect_matches
|
21
|
-
config.on_event(:test_case_started) do |event|
|
22
|
-
formatter.before_test_case(event.test_case)
|
23
|
-
printer.before_test_case(event.test_case)
|
24
|
-
end
|
25
|
-
config.on_event(:test_step_started) do |event|
|
26
|
-
formatter.before_test_step(event.test_step)
|
27
|
-
printer.before_test_step(event.test_step)
|
28
|
-
end
|
29
|
-
config.on_event(:test_step_finished) do |event|
|
30
|
-
test_step, result = *event.attributes
|
31
|
-
printer.after_test_step(test_step, result)
|
32
|
-
formatter.after_test_step(test_step, result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter))
|
33
|
-
end
|
34
|
-
config.on_event(:test_case_finished) do |event|
|
35
|
-
test_case, result = *event.attributes
|
36
|
-
record_test_case_result(test_case, result)
|
37
|
-
printer.after_test_case(test_case, result)
|
38
|
-
formatter.after_test_case(test_case, result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter))
|
39
|
-
end
|
40
|
-
config.on_event(:test_run_finished) do
|
41
|
-
printer.after
|
42
|
-
formatter.done
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def_delegators :formatter, :ask
|
47
|
-
def_delegators :printer, :embed
|
48
|
-
|
49
|
-
def puts(*messages)
|
50
|
-
printer.puts(messages)
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def emit_deprecation_warning
|
56
|
-
parent_name = formatter_class_name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
57
|
-
return if parent_name == 'Cucumber::Formatter'
|
58
|
-
return if !config.out_stream # some unit tests don't set it
|
59
|
-
config.out_stream.puts "WARNING: The formatter #{formatter.class.name} is using the deprecated formatter API which will be removed in v4.0 of Cucumber."
|
60
|
-
config.out_stream.puts
|
61
|
-
end
|
62
|
-
|
63
|
-
def formatter_class_name
|
64
|
-
formatter.class.name
|
65
|
-
rescue NoMethodError # when we use the Fanout, things get gnarly
|
66
|
-
formatter.class[0].class.name
|
67
|
-
end
|
68
|
-
|
69
|
-
def printer
|
70
|
-
@printer ||= FeaturesPrinter.new(formatter, results, config, @matches).before
|
71
|
-
end
|
72
|
-
|
73
|
-
def record_test_case_result(test_case, result)
|
74
|
-
scenario = LegacyResultBuilder.new(result).scenario("#{test_case.keyword}: #{test_case.name}", test_case.location)
|
75
|
-
results.scenario_visited(scenario)
|
76
|
-
end
|
77
|
-
|
78
|
-
def collect_matches
|
79
|
-
result = {}
|
80
|
-
config.on_event(:step_activated) do |event|
|
81
|
-
test_step, step_match = *event.attributes
|
82
|
-
result[test_step.source.last] = step_match
|
83
|
-
end
|
84
|
-
result
|
85
|
-
end
|
86
|
-
|
87
|
-
require 'cucumber/core/test/timer'
|
88
|
-
FeaturesPrinter = Struct.new(:formatter, :results, :config, :matches) do
|
89
|
-
extend Forwardable
|
90
|
-
|
91
|
-
def before
|
92
|
-
timer.start
|
93
|
-
formatter.before_features(nil)
|
94
|
-
self
|
95
|
-
end
|
96
|
-
|
97
|
-
def before_test_case(test_case)
|
98
|
-
test_case.describe_source_to(self)
|
99
|
-
@child.before_test_case(test_case)
|
100
|
-
end
|
101
|
-
|
102
|
-
def before_test_step(*args)
|
103
|
-
@child.before_test_step(*args)
|
104
|
-
end
|
105
|
-
|
106
|
-
def after_test_step(test_step, result)
|
107
|
-
@child.after_test_step(test_step, result)
|
108
|
-
end
|
109
|
-
|
110
|
-
def after_test_case(*args)
|
111
|
-
@child.after_test_case(*args)
|
112
|
-
end
|
113
|
-
|
114
|
-
def feature(node, *)
|
115
|
-
if node != @current_feature
|
116
|
-
@child.after if @child
|
117
|
-
@child = FeaturePrinter.new(formatter, results, matches, config, node).before
|
118
|
-
@current_feature = node
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def scenario(node, *)
|
123
|
-
end
|
124
|
-
|
125
|
-
def scenario_outline(node, *)
|
126
|
-
end
|
127
|
-
|
128
|
-
def examples_table(node, *)
|
129
|
-
end
|
130
|
-
|
131
|
-
def examples_table_row(node, *)
|
132
|
-
end
|
133
|
-
|
134
|
-
def after
|
135
|
-
@child.after if @child
|
136
|
-
formatter.after_features Ast::Features.new(timer.sec)
|
137
|
-
self
|
138
|
-
end
|
139
|
-
|
140
|
-
def puts(messages)
|
141
|
-
@child.puts(messages)
|
142
|
-
end
|
143
|
-
|
144
|
-
def embed(src, mime_type, label)
|
145
|
-
@child.embed(src, mime_type, label)
|
146
|
-
end
|
147
|
-
|
148
|
-
private
|
149
|
-
|
150
|
-
def timer
|
151
|
-
@timer ||= Cucumber::Core::Test::Timer.new
|
152
|
-
end
|
153
|
-
|
154
|
-
end
|
155
|
-
|
156
|
-
module TestCaseSource
|
157
|
-
def self.for(test_case, result)
|
158
|
-
collector = Collector.new
|
159
|
-
test_case.describe_source_to collector, result
|
160
|
-
collector.result.freeze
|
161
|
-
end
|
162
|
-
|
163
|
-
class Collector
|
164
|
-
attr_reader :result
|
165
|
-
|
166
|
-
def initialize
|
167
|
-
@result = CaseSource.new
|
168
|
-
end
|
169
|
-
|
170
|
-
def method_missing(name, node, _test_case_result, *_args)
|
171
|
-
result.send "#{name}=", node
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
require 'ostruct'
|
176
|
-
class CaseSource < OpenStruct
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
module TestStepSource
|
181
|
-
def self.for(test_step, result)
|
182
|
-
collector = Collector.new
|
183
|
-
test_step.describe_source_to collector, result
|
184
|
-
collector.result.freeze
|
185
|
-
end
|
186
|
-
|
187
|
-
class Collector
|
188
|
-
attr_reader :result
|
189
|
-
|
190
|
-
def initialize
|
191
|
-
@result = StepSource.new
|
192
|
-
end
|
193
|
-
|
194
|
-
def method_missing(name, node, step_result, *_args)
|
195
|
-
result.send "#{name}=", node
|
196
|
-
result.send "#{name}_result=", LegacyResultBuilder.new(step_result)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
require 'ostruct'
|
201
|
-
class StepSource < OpenStruct
|
202
|
-
def build_step_invocation(indent, matches, config, messages, embeddings)
|
203
|
-
step_result.step_invocation(
|
204
|
-
matches.fetch(step) { NoStepMatch.new(step, step.text) },
|
205
|
-
step,
|
206
|
-
indent,
|
207
|
-
background,
|
208
|
-
config,
|
209
|
-
messages,
|
210
|
-
embeddings
|
211
|
-
)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
end
|
216
|
-
|
217
|
-
Embedding = Struct.new(:src, :mime_type, :label) do
|
218
|
-
|
219
|
-
def send_to_formatter(formatter)
|
220
|
-
formatter.embed(src, mime_type, label)
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
FeaturePrinter = Struct.new(:formatter, :results, :matches, :config, :node) do
|
225
|
-
|
226
|
-
def before
|
227
|
-
formatter.before_feature(node)
|
228
|
-
language_comment = node.language.iso_code != 'en' ? ["# language: #{node.language.iso_code}"] : []
|
229
|
-
Ast::Comments.new(language_comment + node.comments).accept(formatter)
|
230
|
-
Ast::Tags.new(node.tags).accept(formatter)
|
231
|
-
formatter.feature_name node.keyword, node.legacy_conflated_name_and_description
|
232
|
-
@delayed_messages = []
|
233
|
-
@delayed_embeddings = []
|
234
|
-
self
|
235
|
-
end
|
236
|
-
|
237
|
-
attr_reader :current_test_step_source
|
238
|
-
|
239
|
-
def before_test_case(_test_case)
|
240
|
-
@before_hook_results = Ast::HookResultCollection.new
|
241
|
-
@test_step_results = []
|
242
|
-
end
|
243
|
-
|
244
|
-
def before_test_step(test_step)
|
245
|
-
end
|
246
|
-
|
247
|
-
def after_test_step(test_step, result)
|
248
|
-
@current_test_step_source = TestStepSource.for(test_step, result)
|
249
|
-
# TODO: stop calling self, and describe source to another object
|
250
|
-
test_step.describe_source_to(self, result)
|
251
|
-
print_step
|
252
|
-
@test_step_results << result
|
253
|
-
end
|
254
|
-
|
255
|
-
def after_test_case(test_case, test_case_result)
|
256
|
-
if current_test_step_source && current_test_step_source.step_result.nil?
|
257
|
-
switch_step_container
|
258
|
-
end
|
259
|
-
|
260
|
-
if test_case_result.failed? && !any_test_steps_failed?
|
261
|
-
# around hook must have failed. Print the error.
|
262
|
-
switch_step_container(TestCaseSource.for(test_case, test_case_result))
|
263
|
-
LegacyResultBuilder.new(test_case_result).describe_exception_to formatter
|
264
|
-
end
|
265
|
-
|
266
|
-
# messages and embedding should already have been handled, but just in case...
|
267
|
-
@delayed_messages.each { |message| formatter.puts(message) }
|
268
|
-
@delayed_embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
|
269
|
-
@delayed_messages = []
|
270
|
-
@delayed_embeddings = []
|
271
|
-
|
272
|
-
@child.after_test_case(test_case, test_case_result) if @child
|
273
|
-
@previous_test_case_background = @current_test_case_background
|
274
|
-
@previous_test_case_scenario_outline = current_test_step_source && current_test_step_source.scenario_outline
|
275
|
-
end
|
276
|
-
|
277
|
-
def before_hook(_location, result)
|
278
|
-
@before_hook_results << Ast::HookResult.new(LegacyResultBuilder.new(result), @delayed_messages, @delayed_embeddings)
|
279
|
-
@delayed_messages = []
|
280
|
-
@delayed_embeddings = []
|
281
|
-
end
|
282
|
-
|
283
|
-
def after_hook(_location, result)
|
284
|
-
# if the scenario has no steps, we can hit this before we've created the scenario printer
|
285
|
-
# ideally we should call switch_step_container in before_step_step
|
286
|
-
switch_step_container if !@child
|
287
|
-
@child.after_hook Ast::HookResult.new(LegacyResultBuilder.new(result), @delayed_messages, @delayed_embeddings)
|
288
|
-
@delayed_messages = []
|
289
|
-
@delayed_embeddings = []
|
290
|
-
end
|
291
|
-
|
292
|
-
def after_step_hook(_hook, result)
|
293
|
-
p current_test_step_source if current_test_step_source.step.nil?
|
294
|
-
line = current_test_step_source.step.backtrace_line
|
295
|
-
@child.after_step_hook Ast::HookResult.new(LegacyResultBuilder.new(result).
|
296
|
-
append_to_exception_backtrace(line), @delayed_messages, @delayed_embeddings)
|
297
|
-
@delayed_messages = []
|
298
|
-
@delayed_embeddings = []
|
299
|
-
end
|
300
|
-
|
301
|
-
def background(node, *)
|
302
|
-
@current_test_case_background = node
|
303
|
-
end
|
304
|
-
|
305
|
-
def puts(messages)
|
306
|
-
@delayed_messages.push *messages
|
307
|
-
end
|
308
|
-
|
309
|
-
def embed(src, mime_type, label)
|
310
|
-
@delayed_embeddings.push Embedding.new(src, mime_type, label)
|
311
|
-
end
|
312
|
-
|
313
|
-
def step(*);end
|
314
|
-
def scenario(*);end
|
315
|
-
def scenario_outline(*);end
|
316
|
-
def examples_table(*);end
|
317
|
-
def examples_table_row(*);end
|
318
|
-
def feature(*);end
|
319
|
-
|
320
|
-
def after
|
321
|
-
@child.after if @child
|
322
|
-
formatter.after_feature(node)
|
323
|
-
self
|
324
|
-
end
|
325
|
-
|
326
|
-
private
|
327
|
-
|
328
|
-
attr_reader :before_hook_results
|
329
|
-
private :before_hook_results
|
330
|
-
|
331
|
-
def any_test_steps_failed?
|
332
|
-
@test_step_results.any? &:failed?
|
333
|
-
end
|
334
|
-
|
335
|
-
def switch_step_container(source = current_test_step_source)
|
336
|
-
switch_to_child select_step_container(source), source
|
337
|
-
end
|
338
|
-
|
339
|
-
def select_step_container(source)
|
340
|
-
if source.background
|
341
|
-
if same_background_as_previous_test_case?(source)
|
342
|
-
HiddenBackgroundPrinter.new(formatter, source.background)
|
343
|
-
else
|
344
|
-
BackgroundPrinter.new(formatter, node, source.background, before_hook_results)
|
345
|
-
end
|
346
|
-
elsif source.scenario
|
347
|
-
ScenarioPrinter.new(formatter, source.scenario, before_hook_results)
|
348
|
-
elsif source.scenario_outline
|
349
|
-
if same_scenario_outline_as_previous_test_case?(source) && @previous_outline_child
|
350
|
-
@previous_outline_child
|
351
|
-
else
|
352
|
-
ScenarioOutlinePrinter.new(formatter, config, source.scenario_outline)
|
353
|
-
end
|
354
|
-
else
|
355
|
-
raise 'unknown step container'
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
def same_background_as_previous_test_case?(source)
|
360
|
-
source.background == @previous_test_case_background
|
361
|
-
end
|
362
|
-
|
363
|
-
def same_scenario_outline_as_previous_test_case?(source)
|
364
|
-
source.scenario_outline == @previous_test_case_scenario_outline
|
365
|
-
end
|
366
|
-
|
367
|
-
def print_step
|
368
|
-
return unless current_test_step_source.step_result
|
369
|
-
switch_step_container
|
370
|
-
|
371
|
-
if current_test_step_source.scenario_outline
|
372
|
-
@child.examples_table(current_test_step_source.examples_table)
|
373
|
-
@child.examples_table_row(current_test_step_source.examples_table_row, before_hook_results)
|
374
|
-
end
|
375
|
-
|
376
|
-
if @failed_hidden_background_step
|
377
|
-
indent = Indent.new(@child.node)
|
378
|
-
step_invocation = @failed_hidden_background_step.build_step_invocation(indent, matches, config, [], [])
|
379
|
-
@child.step_invocation(step_invocation, @failed_hidden_background_step)
|
380
|
-
@failed_hidden_background_step = nil
|
381
|
-
end
|
382
|
-
|
383
|
-
unless @last_step == current_test_step_source.step
|
384
|
-
indent ||= Indent.new(@child.node)
|
385
|
-
step_invocation = current_test_step_source.build_step_invocation(indent, matches, config, @delayed_messages, @delayed_embeddings)
|
386
|
-
results.step_visited step_invocation
|
387
|
-
@child.step_invocation(step_invocation, current_test_step_source)
|
388
|
-
@last_step = current_test_step_source.step
|
389
|
-
end
|
390
|
-
@delayed_messages = []
|
391
|
-
@delayed_embeddings = []
|
392
|
-
end
|
393
|
-
|
394
|
-
def switch_to_child(child, source)
|
395
|
-
return if @child == child
|
396
|
-
if @child
|
397
|
-
if from_first_background(@child)
|
398
|
-
@first_background_failed = @child.failed?
|
399
|
-
elsif from_hidden_background(@child)
|
400
|
-
if not @first_background_failed
|
401
|
-
@failed_hidden_background_step = @child.get_failed_step_source
|
402
|
-
end
|
403
|
-
if @previous_outline_child
|
404
|
-
@previous_outline_child.after unless same_scenario_outline_as_previous_test_case?(source)
|
405
|
-
end
|
406
|
-
end
|
407
|
-
if from_scenario_outline_to_hidden_background(@child, child)
|
408
|
-
@previous_outline_child = @child
|
409
|
-
else
|
410
|
-
@child.after
|
411
|
-
@previous_outline_child = nil
|
412
|
-
end
|
413
|
-
end
|
414
|
-
child.before unless to_scenario_outline(child) && same_scenario_outline_as_previous_test_case?(source)
|
415
|
-
@child = child
|
416
|
-
end
|
417
|
-
|
418
|
-
def from_scenario_outline_to_hidden_background(from, to)
|
419
|
-
from.class.name == ScenarioOutlinePrinter.name &&
|
420
|
-
to.class.name == HiddenBackgroundPrinter.name
|
421
|
-
end
|
422
|
-
|
423
|
-
def from_first_background(from)
|
424
|
-
from.class.name == BackgroundPrinter.name
|
425
|
-
end
|
426
|
-
|
427
|
-
def from_hidden_background(from)
|
428
|
-
from.class.name == HiddenBackgroundPrinter.name
|
429
|
-
end
|
430
|
-
|
431
|
-
def to_scenario_outline(to)
|
432
|
-
to.class.name == ScenarioOutlinePrinter.name
|
433
|
-
end
|
434
|
-
|
435
|
-
end
|
436
|
-
|
437
|
-
module PrintsAfterHooks
|
438
|
-
def after_hook_results
|
439
|
-
@after_hook_results ||= Ast::HookResultCollection.new
|
440
|
-
end
|
441
|
-
|
442
|
-
def after_hook(result)
|
443
|
-
after_hook_results << result
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
# Basic printer used by default
|
448
|
-
class AfterHookPrinter
|
449
|
-
attr_reader :formatter
|
450
|
-
|
451
|
-
def initialize(formatter)
|
452
|
-
@formatter = formatter
|
453
|
-
end
|
454
|
-
|
455
|
-
include PrintsAfterHooks
|
456
|
-
|
457
|
-
def after
|
458
|
-
after_hook_results.accept(formatter)
|
459
|
-
end
|
460
|
-
end
|
461
|
-
|
462
|
-
BackgroundPrinter = Struct.new(:formatter, :feature, :node, :before_hook_results) do
|
463
|
-
|
464
|
-
def after_test_case(*)
|
465
|
-
end
|
466
|
-
|
467
|
-
def after_hook(*)
|
468
|
-
end
|
469
|
-
|
470
|
-
def before
|
471
|
-
formatter.before_background Ast::Background.new(feature, node)
|
472
|
-
Ast::Comments.new(node.comments).accept(formatter)
|
473
|
-
formatter.background_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
|
474
|
-
before_hook_results.accept(formatter)
|
475
|
-
self
|
476
|
-
end
|
477
|
-
|
478
|
-
def after_step_hook(result)
|
479
|
-
result.accept formatter
|
480
|
-
end
|
481
|
-
|
482
|
-
def step_invocation(step_invocation, source)
|
483
|
-
@child ||= StepsPrinter.new(formatter).before
|
484
|
-
@child.step_invocation step_invocation
|
485
|
-
if source.step_result.status == :failed
|
486
|
-
@failed = true
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
|
-
def after
|
491
|
-
@child.after if @child
|
492
|
-
formatter.after_background(Ast::Background.new(feature, node))
|
493
|
-
self
|
494
|
-
end
|
495
|
-
|
496
|
-
def failed?
|
497
|
-
@failed
|
498
|
-
end
|
499
|
-
|
500
|
-
private
|
501
|
-
|
502
|
-
def indent
|
503
|
-
@indent ||= Indent.new(node)
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
# Printer to handle background steps for anything but the first scenario in a
|
508
|
-
# feature. These steps should not be printed.
|
509
|
-
class HiddenBackgroundPrinter < Struct.new(:formatter, :node)
|
510
|
-
def get_failed_step_source
|
511
|
-
return @source_of_failed_step
|
512
|
-
end
|
513
|
-
|
514
|
-
def step_invocation(_step_invocation, source)
|
515
|
-
if source.step_result.status == :failed
|
516
|
-
@source_of_failed_step = source
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
|
-
def before;self;end
|
521
|
-
def after;self;end
|
522
|
-
def before_hook(*);end
|
523
|
-
def after_hook(*);end
|
524
|
-
def after_step_hook(*);end
|
525
|
-
def examples_table(*);end
|
526
|
-
def after_test_case(*);end
|
527
|
-
end
|
528
|
-
|
529
|
-
ScenarioPrinter = Struct.new(:formatter, :node, :before_hook_results) do
|
530
|
-
include PrintsAfterHooks
|
531
|
-
|
532
|
-
def before
|
533
|
-
formatter.before_feature_element(node)
|
534
|
-
Ast::Comments.new(node.comments).accept(formatter)
|
535
|
-
Ast::Tags.new(node.tags).accept(formatter)
|
536
|
-
formatter.scenario_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
|
537
|
-
before_hook_results.accept(formatter)
|
538
|
-
self
|
539
|
-
end
|
540
|
-
|
541
|
-
def step_invocation(step_invocation, _source)
|
542
|
-
@child ||= StepsPrinter.new(formatter).before
|
543
|
-
@child.step_invocation step_invocation
|
544
|
-
end
|
545
|
-
|
546
|
-
def after_step_hook(result)
|
547
|
-
result.accept formatter
|
548
|
-
end
|
549
|
-
|
550
|
-
def after_test_case(_test_case, result)
|
551
|
-
@test_case_result = result
|
552
|
-
after
|
553
|
-
end
|
554
|
-
|
555
|
-
def after
|
556
|
-
return if @done
|
557
|
-
@child.after if @child
|
558
|
-
scenario = LegacyResultBuilder.new(@test_case_result).scenario(node.name, node.location)
|
559
|
-
after_hook_results.accept(formatter)
|
560
|
-
formatter.after_feature_element(scenario)
|
561
|
-
@done = true
|
562
|
-
self
|
563
|
-
end
|
564
|
-
|
565
|
-
private
|
566
|
-
|
567
|
-
def indent
|
568
|
-
@indent ||= Indent.new(node)
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
|
-
StepsPrinter = Struct.new(:formatter) do
|
573
|
-
def before
|
574
|
-
formatter.before_steps(nil)
|
575
|
-
self
|
576
|
-
end
|
577
|
-
|
578
|
-
def step_invocation(step_invocation)
|
579
|
-
steps << step_invocation
|
580
|
-
step_invocation.accept(formatter)
|
581
|
-
self
|
582
|
-
end
|
583
|
-
|
584
|
-
def after
|
585
|
-
formatter.after_steps(steps)
|
586
|
-
self
|
587
|
-
end
|
588
|
-
|
589
|
-
private
|
590
|
-
|
591
|
-
def steps
|
592
|
-
@steps ||= Ast::StepInvocations.new
|
593
|
-
end
|
594
|
-
|
595
|
-
end
|
596
|
-
|
597
|
-
ScenarioOutlinePrinter = Struct.new(:formatter, :configuration, :node) do
|
598
|
-
extend Forwardable
|
599
|
-
def_delegators :@child, :after_hook, :after_step_hook
|
600
|
-
|
601
|
-
def before
|
602
|
-
formatter.before_feature_element(node)
|
603
|
-
Ast::Comments.new(node.comments).accept(formatter)
|
604
|
-
Ast::Tags.new(node.tags).accept(formatter)
|
605
|
-
formatter.scenario_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
|
606
|
-
OutlineStepsPrinter.new(formatter, configuration, indent).print(node)
|
607
|
-
self
|
608
|
-
end
|
609
|
-
|
610
|
-
def step_invocation(step_invocation, source)
|
611
|
-
_node, result = source.step, source.step_result
|
612
|
-
@last_step_result = result
|
613
|
-
@child.step_invocation(step_invocation, source)
|
614
|
-
end
|
615
|
-
|
616
|
-
def examples_table(examples_table)
|
617
|
-
@child ||= ExamplesArrayPrinter.new(formatter, configuration).before
|
618
|
-
@child.examples_table(examples_table)
|
619
|
-
end
|
620
|
-
|
621
|
-
def examples_table_row(node, before_hook_results)
|
622
|
-
@child.examples_table_row(node, before_hook_results)
|
623
|
-
end
|
624
|
-
|
625
|
-
def after_test_case(test_case, result)
|
626
|
-
@child.after_test_case(test_case, result)
|
627
|
-
end
|
628
|
-
|
629
|
-
def after
|
630
|
-
@child.after if @child
|
631
|
-
# TODO: the last step result might not accurately reflect the
|
632
|
-
# overall scenario result.
|
633
|
-
scenario_outline = last_step_result.scenario_outline(node.name, node.location)
|
634
|
-
formatter.after_feature_element(scenario_outline)
|
635
|
-
self
|
636
|
-
end
|
637
|
-
|
638
|
-
private
|
639
|
-
|
640
|
-
def last_step_result
|
641
|
-
@last_step_result || Core::Test::Result::Unknown.new
|
642
|
-
end
|
643
|
-
|
644
|
-
def indent
|
645
|
-
@indent ||= Indent.new(node)
|
646
|
-
end
|
647
|
-
end
|
648
|
-
|
649
|
-
OutlineStepsPrinter = Struct.new(:formatter, :configuration, :indent, :outline) do
|
650
|
-
def print(node)
|
651
|
-
node.describe_to self
|
652
|
-
steps_printer.after
|
653
|
-
end
|
654
|
-
|
655
|
-
def scenario_outline(_node, &descend)
|
656
|
-
descend.call(self)
|
657
|
-
end
|
658
|
-
|
659
|
-
def outline_step(step)
|
660
|
-
step_match = NoStepMatch.new(step, step.text)
|
661
|
-
step_invocation = LegacyResultBuilder.new(Core::Test::Result::Skipped.new).
|
662
|
-
step_invocation(step_match, step, indent, nil, configuration, [], [])
|
663
|
-
steps_printer.step_invocation step_invocation
|
664
|
-
end
|
665
|
-
|
666
|
-
def examples_table(*);end
|
667
|
-
|
668
|
-
private
|
669
|
-
|
670
|
-
def steps_printer
|
671
|
-
@steps_printer ||= StepsPrinter.new(formatter).before
|
672
|
-
end
|
673
|
-
end
|
674
|
-
|
675
|
-
ExamplesArrayPrinter = Struct.new(:formatter, :configuration) do
|
676
|
-
extend Forwardable
|
677
|
-
def_delegators :@child, :step_invocation, :after_hook, :after_step_hook, :after_test_case, :examples_table_row
|
678
|
-
|
679
|
-
def before
|
680
|
-
formatter.before_examples_array(:examples_array)
|
681
|
-
self
|
682
|
-
end
|
683
|
-
|
684
|
-
def examples_table(examples_table)
|
685
|
-
return if examples_table == @current
|
686
|
-
@child.after if @child
|
687
|
-
@child = ExamplesTablePrinter.new(formatter, configuration, examples_table).before
|
688
|
-
@current = examples_table
|
689
|
-
end
|
690
|
-
|
691
|
-
def after
|
692
|
-
@child.after if @child
|
693
|
-
formatter.after_examples_array
|
694
|
-
self
|
695
|
-
end
|
696
|
-
end
|
697
|
-
|
698
|
-
ExamplesTablePrinter = Struct.new(:formatter, :configuration, :node) do
|
699
|
-
extend Forwardable
|
700
|
-
def_delegators :@child, :step_invocation, :after_hook, :after_step_hook, :after_test_case
|
701
|
-
|
702
|
-
def before
|
703
|
-
formatter.before_examples(node)
|
704
|
-
Ast::Comments.new(node.comments).accept(formatter)
|
705
|
-
Ast::Tags.new(node.tags).accept(formatter)
|
706
|
-
formatter.examples_name(node.keyword, node.legacy_conflated_name_and_description)
|
707
|
-
formatter.before_outline_table(legacy_table)
|
708
|
-
if !configuration.expand?
|
709
|
-
HeaderTableRowPrinter.new(formatter, ExampleTableRow.new(node.header), Ast::Node.new).before.after
|
710
|
-
end
|
711
|
-
self
|
712
|
-
end
|
713
|
-
|
714
|
-
def examples_table_row(examples_table_row, before_hook_results)
|
715
|
-
return if examples_table_row == @current
|
716
|
-
@child.after if @child
|
717
|
-
row = ExampleTableRow.new(examples_table_row)
|
718
|
-
@child = if !configuration.expand?
|
719
|
-
TableRowPrinter.new(formatter, row, before_hook_results).before
|
720
|
-
else
|
721
|
-
ExpandTableRowPrinter.new(formatter, row, before_hook_results).before
|
722
|
-
end
|
723
|
-
@current = examples_table_row
|
724
|
-
end
|
725
|
-
|
726
|
-
def after_test_case(*args)
|
727
|
-
@child.after_test_case(*args)
|
728
|
-
end
|
729
|
-
|
730
|
-
def after
|
731
|
-
@child.after if @child
|
732
|
-
formatter.after_outline_table(node)
|
733
|
-
formatter.after_examples(node)
|
734
|
-
self
|
735
|
-
end
|
736
|
-
|
737
|
-
private
|
738
|
-
|
739
|
-
def legacy_table
|
740
|
-
LegacyTable.new(node)
|
741
|
-
end
|
742
|
-
|
743
|
-
class ExampleTableRow < SimpleDelegator
|
744
|
-
def dom_id
|
745
|
-
file_colon_line.gsub(/[\/\.:]/, '_')
|
746
|
-
end
|
747
|
-
end
|
748
|
-
|
749
|
-
LegacyTable = Struct.new(:node) do
|
750
|
-
def col_width(index)
|
751
|
-
max_width = FindMaxWidth.new(index)
|
752
|
-
node.describe_to max_width
|
753
|
-
max_width.result
|
754
|
-
end
|
755
|
-
|
756
|
-
require 'cucumber/gherkin/formatter/escaping'
|
757
|
-
FindMaxWidth = Struct.new(:index) do
|
758
|
-
include ::Cucumber::Gherkin::Formatter::Escaping
|
759
|
-
|
760
|
-
def examples_table(table, &descend)
|
761
|
-
@result = char_length_of(table.header.values[index])
|
762
|
-
descend.call(self)
|
763
|
-
end
|
764
|
-
|
765
|
-
def examples_table_row(row, &_descend)
|
766
|
-
width = char_length_of(row.values[index])
|
767
|
-
@result = width if width > result
|
768
|
-
end
|
769
|
-
|
770
|
-
def result
|
771
|
-
@result ||= 0
|
772
|
-
end
|
773
|
-
|
774
|
-
private
|
775
|
-
def char_length_of(cell)
|
776
|
-
escape_cell(cell).unpack('U*').length
|
777
|
-
end
|
778
|
-
end
|
779
|
-
end
|
780
|
-
end
|
781
|
-
|
782
|
-
class TableRowPrinterBase < Struct.new(:formatter, :node, :before_hook_results)
|
783
|
-
include PrintsAfterHooks
|
784
|
-
|
785
|
-
def after_step_hook(result)
|
786
|
-
@after_step_hook_result ||= Ast::HookResultCollection.new
|
787
|
-
@after_step_hook_result << result
|
788
|
-
end
|
789
|
-
|
790
|
-
def after_test_case(*_args)
|
791
|
-
after
|
792
|
-
end
|
793
|
-
|
794
|
-
private
|
795
|
-
|
796
|
-
def indent
|
797
|
-
:not_needed
|
798
|
-
end
|
799
|
-
|
800
|
-
def legacy_table_row
|
801
|
-
Ast::ExampleTableRow.new(exception, @status, node.values, node.location, node.language)
|
802
|
-
end
|
803
|
-
|
804
|
-
def exception
|
805
|
-
return nil unless @failed_step
|
806
|
-
@failed_step.exception
|
807
|
-
end
|
808
|
-
end
|
809
|
-
|
810
|
-
class HeaderTableRowPrinter < TableRowPrinterBase
|
811
|
-
def legacy_table_row
|
812
|
-
Ast::ExampleTableRow.new(exception, @status, node.values, node.location, Ast::NullLanguage.new)
|
813
|
-
end
|
814
|
-
|
815
|
-
def before
|
816
|
-
Ast::Comments.new(node.comments).accept(formatter)
|
817
|
-
formatter.before_table_row(node)
|
818
|
-
self
|
819
|
-
end
|
820
|
-
|
821
|
-
def after
|
822
|
-
node.values.each do |value|
|
823
|
-
formatter.before_table_cell(value)
|
824
|
-
formatter.table_cell_value(value, :skipped_param)
|
825
|
-
formatter.after_table_cell(value)
|
826
|
-
end
|
827
|
-
formatter.after_table_row(legacy_table_row)
|
828
|
-
self
|
829
|
-
end
|
830
|
-
end
|
831
|
-
|
832
|
-
|
833
|
-
class TableRowPrinter < TableRowPrinterBase
|
834
|
-
def before
|
835
|
-
before_hook_results.accept(formatter)
|
836
|
-
Ast::Comments.new(node.comments).accept(formatter)
|
837
|
-
formatter.before_table_row(node)
|
838
|
-
self
|
839
|
-
end
|
840
|
-
|
841
|
-
def step_invocation(step_invocation, source)
|
842
|
-
result = source.step_result
|
843
|
-
step_invocation.messages.each { |message| formatter.puts(message) }
|
844
|
-
step_invocation.embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
|
845
|
-
@failed_step = step_invocation if result.status == :failed
|
846
|
-
@status = step_invocation.status unless already_failed?
|
847
|
-
end
|
848
|
-
|
849
|
-
def after
|
850
|
-
return if @done
|
851
|
-
@child.after if @child
|
852
|
-
node.values.each do |value|
|
853
|
-
formatter.before_table_cell(value)
|
854
|
-
formatter.table_cell_value(value, @status || :skipped)
|
855
|
-
formatter.after_table_cell(value)
|
856
|
-
end
|
857
|
-
@after_step_hook_result.send_output_to(formatter) if @after_step_hook_result
|
858
|
-
after_hook_results.send_output_to(formatter)
|
859
|
-
formatter.after_table_row(legacy_table_row)
|
860
|
-
@after_step_hook_result.describe_exception_to(formatter) if @after_step_hook_result
|
861
|
-
after_hook_results.describe_exception_to(formatter)
|
862
|
-
@done = true
|
863
|
-
self
|
864
|
-
end
|
865
|
-
|
866
|
-
private
|
867
|
-
|
868
|
-
def already_failed?
|
869
|
-
@status == :failed || @status == :undefined || @status == :pending
|
870
|
-
end
|
871
|
-
end
|
872
|
-
|
873
|
-
class ExpandTableRowPrinter < TableRowPrinterBase
|
874
|
-
def before
|
875
|
-
before_hook_results.accept(formatter)
|
876
|
-
self
|
877
|
-
end
|
878
|
-
|
879
|
-
def step_invocation(step_invocation, source)
|
880
|
-
result = source.step_result
|
881
|
-
@table_row ||= legacy_table_row
|
882
|
-
step_invocation.indent.record_width_of(@table_row)
|
883
|
-
if !@scenario_name_printed
|
884
|
-
print_scenario_name(step_invocation, @table_row)
|
885
|
-
@scenario_name_printed = true
|
886
|
-
end
|
887
|
-
step_invocation.accept(formatter)
|
888
|
-
@failed_step = step_invocation if result.status == :failed
|
889
|
-
@status = step_invocation.status unless @status == :failed
|
890
|
-
end
|
891
|
-
|
892
|
-
def after
|
893
|
-
return if @done
|
894
|
-
@child.after if @child
|
895
|
-
@after_step_hook_result.accept(formatter) if @after_step_hook_result
|
896
|
-
after_hook_results.accept(formatter)
|
897
|
-
@done = true
|
898
|
-
self
|
899
|
-
end
|
900
|
-
|
901
|
-
private
|
902
|
-
|
903
|
-
def print_scenario_name(step_invocation, table_row)
|
904
|
-
formatter.scenario_name table_row.keyword, table_row.name, node.location.to_s, step_invocation.indent.of(table_row)
|
905
|
-
end
|
906
|
-
end
|
907
|
-
|
908
|
-
class Indent
|
909
|
-
def initialize(node)
|
910
|
-
@widths = []
|
911
|
-
node.describe_to(self)
|
912
|
-
end
|
913
|
-
|
914
|
-
[:background, :scenario, :scenario_outline].each do |node_name|
|
915
|
-
define_method(node_name) do |node, &descend|
|
916
|
-
record_width_of node
|
917
|
-
descend.call(self)
|
918
|
-
end
|
919
|
-
end
|
920
|
-
|
921
|
-
[:step, :outline_step].each do |node_name|
|
922
|
-
define_method(node_name) do |node|
|
923
|
-
record_width_of node
|
924
|
-
end
|
925
|
-
end
|
926
|
-
|
927
|
-
def examples_table(*); end
|
928
|
-
def examples_table_row(*); end
|
929
|
-
|
930
|
-
def of(node)
|
931
|
-
# The length of the instantiated steps in --expand mode are currently
|
932
|
-
# not included in the calculation of max => make sure to return >= 1
|
933
|
-
[1, max - node.to_s.length - node.keyword.length].max
|
934
|
-
end
|
935
|
-
|
936
|
-
def record_width_of(node)
|
937
|
-
@widths << node.keyword.length + node.to_s.length + 1
|
938
|
-
end
|
939
|
-
|
940
|
-
private
|
941
|
-
|
942
|
-
def max
|
943
|
-
@widths.max
|
944
|
-
end
|
945
|
-
end
|
946
|
-
|
947
|
-
class LegacyResultBuilder
|
948
|
-
attr_reader :status
|
949
|
-
def initialize(result)
|
950
|
-
@result = result
|
951
|
-
@result.describe_to(self)
|
952
|
-
end
|
953
|
-
|
954
|
-
def passed
|
955
|
-
@status = :passed
|
956
|
-
end
|
957
|
-
|
958
|
-
def failed
|
959
|
-
@status = :failed
|
960
|
-
end
|
961
|
-
|
962
|
-
def undefined
|
963
|
-
@status = :undefined
|
964
|
-
end
|
965
|
-
|
966
|
-
def skipped
|
967
|
-
@status = :skipped
|
968
|
-
end
|
969
|
-
|
970
|
-
def pending(exception, *)
|
971
|
-
@exception = exception
|
972
|
-
@status = :pending
|
973
|
-
end
|
974
|
-
|
975
|
-
def exception(exception, *)
|
976
|
-
@exception = exception
|
977
|
-
end
|
978
|
-
|
979
|
-
def append_to_exception_backtrace(line)
|
980
|
-
@exception.set_backtrace(@exception.backtrace + [line.to_s]) if @exception
|
981
|
-
return self
|
982
|
-
end
|
983
|
-
|
984
|
-
def duration(duration, *)
|
985
|
-
@duration = duration
|
986
|
-
end
|
987
|
-
|
988
|
-
def step_invocation(step_match, step, indent, background, configuration, messages, embeddings)
|
989
|
-
Ast::StepInvocation.new(step_match, @status, @duration, step_exception(step, configuration), indent, background, step, messages, embeddings)
|
990
|
-
end
|
991
|
-
|
992
|
-
def scenario(name, location)
|
993
|
-
Ast::Scenario.new(@status, name, location)
|
994
|
-
end
|
995
|
-
|
996
|
-
def scenario_outline(name, location)
|
997
|
-
Ast::ScenarioOutline.new(@status, name, location)
|
998
|
-
end
|
999
|
-
|
1000
|
-
def describe_exception_to(formatter)
|
1001
|
-
formatter.exception(filtered_exception, @status) if @exception
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
private
|
1005
|
-
|
1006
|
-
def step_exception(step, configuration)
|
1007
|
-
return filtered_step_exception(step) if @exception
|
1008
|
-
return nil unless @status == :undefined && configuration.strict.strict?(:undefined)
|
1009
|
-
@exception = Cucumber::Undefined.from(@result, step.text)
|
1010
|
-
@exception.backtrace << step.backtrace_line
|
1011
|
-
filtered_step_exception(step)
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
def filtered_exception
|
1015
|
-
Cucumber::Formatter::BacktraceFilter.new(@exception.dup).exception
|
1016
|
-
end
|
1017
|
-
|
1018
|
-
def filtered_step_exception(_step)
|
1019
|
-
exception = filtered_exception
|
1020
|
-
return Cucumber::Formatter::BacktraceFilter.new(exception).exception
|
1021
|
-
end
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
end
|
1025
|
-
|
1026
|
-
end
|
1027
|
-
end
|
1028
|
-
end
|