cucumber 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +7 -9
- data/History.md +295 -265
- data/README.md +9 -7
- data/cucumber.gemspec +2 -2
- data/features/docs/cli/dry_run.feature +0 -3
- data/features/docs/cli/finding_steps.feature +28 -0
- data/features/docs/cli/run_specific_scenarios.feature +3 -1
- data/features/docs/cli/specifying_multiple_formatters.feature +22 -1
- data/features/docs/defining_steps/nested_steps.feature +0 -1
- data/features/docs/defining_steps/printing_messages.feature +4 -4
- data/features/docs/defining_steps/skip_scenario.feature +0 -2
- data/features/docs/exception_in_around_hook.feature +1 -3
- data/features/docs/formatters/html_formatter.feature +1 -0
- data/features/docs/formatters/json_formatter.feature +73 -62
- data/features/docs/formatters/junit_formatter.feature +130 -38
- data/features/docs/formatters/rerun_formatter.feature +60 -8
- data/features/docs/formatters/usage_formatter.feature +3 -7
- data/features/docs/getting_started.feature +1 -1
- data/features/docs/gherkin/background.feature +0 -11
- data/features/docs/gherkin/language_help.feature +5 -0
- data/features/docs/gherkin/outlines.feature +1 -3
- data/features/docs/gherkin/using_descriptions.feature +0 -1
- data/features/docs/raketask.feature +1 -1
- data/features/docs/writing_support_code/after_hooks.feature +22 -0
- data/features/lib/step_definitions/aruba_steps.rb +4 -0
- data/features/lib/step_definitions/junit_steps.rb +1 -1
- data/features/lib/support/normalise_output.rb +21 -4
- data/lib/cucumber/cli/configuration.rb +16 -13
- data/lib/cucumber/cli/main.rb +35 -10
- data/lib/cucumber/cli/options.rb +33 -9
- data/lib/cucumber/cli/rerun_file.rb +29 -0
- data/lib/cucumber/filters/prepare_world.rb +2 -3
- data/lib/cucumber/formatter/backtrace_filter.rb +40 -0
- data/lib/cucumber/formatter/console.rb +2 -3
- data/lib/cucumber/formatter/cucumber.css +1 -0
- data/lib/cucumber/formatter/duration_extractor.rb +28 -0
- data/lib/cucumber/formatter/hook_query_visitor.rb +40 -0
- data/lib/cucumber/formatter/html.rb +16 -1
- data/lib/cucumber/formatter/json.rb +287 -8
- data/lib/cucumber/formatter/junit.rb +92 -143
- data/lib/cucumber/formatter/legacy_api/adapter.rb +18 -54
- data/lib/cucumber/formatter/legacy_api/ast.rb +13 -0
- data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +4 -0
- data/lib/cucumber/formatter/pretty.rb +2 -1
- data/lib/cucumber/formatter/progress.rb +20 -53
- data/lib/cucumber/formatter/rerun.rb +2 -1
- data/lib/cucumber/formatter/usage.rb +16 -22
- data/lib/cucumber/hooks.rb +18 -9
- data/lib/cucumber/multiline_argument/data_table.rb +40 -28
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/rb_support/rb_hook.rb +4 -0
- data/lib/cucumber/running_test_case.rb +13 -4
- data/lib/cucumber/runtime/after_hooks.rb +7 -6
- data/lib/cucumber/runtime/before_hooks.rb +8 -4
- data/lib/cucumber/runtime/step_hooks.rb +5 -4
- data/lib/cucumber/runtime/support_code.rb +6 -15
- data/lib/cucumber/step_match.rb +1 -1
- data/spec/cucumber/cli/configuration_spec.rb +32 -5
- data/spec/cucumber/cli/main_spec.rb +3 -3
- data/spec/cucumber/cli/options_spec.rb +60 -1
- data/spec/cucumber/cli/rerun_spec.rb +89 -0
- data/spec/cucumber/formatter/html_spec.rb +84 -5
- data/spec/cucumber/formatter/json_spec.rb +757 -0
- data/spec/cucumber/formatter/junit_spec.rb +5 -5
- data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +69 -8
- data/spec/cucumber/formatter/pretty_spec.rb +96 -0
- data/spec/cucumber/formatter/progress_spec.rb +85 -1
- data/spec/cucumber/formatter/rerun_spec.rb +3 -3
- data/spec/cucumber/multiline_argument/data_table_spec.rb +89 -0
- data/spec/cucumber/running_test_case_spec.rb +57 -1
- metadata +70 -60
- data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +0 -204
- data/lib/cucumber/formatter/gpretty.rb +0 -24
@@ -8,10 +8,6 @@ module Cucumber
|
|
8
8
|
# The formatter used for <tt>--format junit</tt>
|
9
9
|
class Junit
|
10
10
|
|
11
|
-
# TODO: remove coupling to types
|
12
|
-
AST_SCENARIO_OUTLINE = Core::Ast::ScenarioOutline
|
13
|
-
AST_EXAMPLE_ROW = LegacyApi::Ast::ExampleTableRow
|
14
|
-
|
15
11
|
include Io
|
16
12
|
|
17
13
|
class UnNamedFeatureError < StandardError
|
@@ -20,168 +16,129 @@ module Cucumber
|
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
23
|
-
def initialize(
|
19
|
+
def initialize(_runtime, io, options)
|
24
20
|
@reportdir = ensure_dir(io, "junit")
|
25
21
|
@options = options
|
26
22
|
end
|
27
23
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
def before_test_case(test_case)
|
25
|
+
unless same_feature_as_previous_test_case?(test_case.feature)
|
26
|
+
end_feature if @current_feature
|
27
|
+
start_feature(test_case.feature)
|
28
|
+
end
|
29
|
+
@failing_step_source = nil
|
33
30
|
# In order to fill out <system-err/> and <system-out/>, we need to
|
34
31
|
# intercept the $stderr and $stdout
|
35
32
|
@interceptedout = Interceptor::Pipe.wrap(:stdout)
|
36
33
|
@interceptederr = Interceptor::Pipe.wrap(:stderr)
|
37
34
|
end
|
38
35
|
|
39
|
-
def
|
40
|
-
|
41
|
-
@steps_start = Time.now
|
42
|
-
end
|
36
|
+
def after_test_step(test_step, result)
|
37
|
+
return if @failing_step_source
|
43
38
|
|
44
|
-
|
45
|
-
|
46
|
-
@testsuite.instruct!
|
47
|
-
@testsuite.testsuite(
|
48
|
-
:failures => @failures,
|
49
|
-
:errors => @errors,
|
50
|
-
:skipped => @skipped,
|
51
|
-
:tests => @tests,
|
52
|
-
:time => "%.6f" % @time,
|
53
|
-
:name => @feature_name ) do
|
54
|
-
@testsuite << @builder.target!
|
55
|
-
@testsuite.tag!('system-out') do
|
56
|
-
@testsuite.cdata! strip_control_chars(@interceptedout.buffer.join)
|
57
|
-
end
|
58
|
-
@testsuite.tag!('system-err') do
|
59
|
-
@testsuite.cdata! strip_control_chars(@interceptederr.buffer.join)
|
60
|
-
end
|
61
|
-
end
|
39
|
+
@failing_step_source = test_step.source.last unless result.ok?(@options[:strict])
|
40
|
+
end
|
62
41
|
|
63
|
-
|
42
|
+
def after_test_case(test_case, result)
|
43
|
+
test_case_name = NameBuilder.new(test_case)
|
44
|
+
scenario = test_case_name.scenario_name
|
45
|
+
scenario_designation = "#{scenario}#{test_case_name.name_suffix}"
|
46
|
+
output = create_output_string(test_case, scenario, result, test_case_name.row_name)
|
47
|
+
build_testcase(result, scenario_designation, output)
|
64
48
|
|
65
49
|
Interceptor::Pipe.unwrap! :stdout
|
66
50
|
Interceptor::Pipe.unwrap! :stderr
|
67
51
|
end
|
68
52
|
|
69
|
-
def
|
70
|
-
|
53
|
+
def done
|
54
|
+
end_feature if @current_feature
|
71
55
|
end
|
72
56
|
|
73
|
-
|
74
|
-
@in_background = false
|
75
|
-
end
|
76
|
-
|
77
|
-
def feature_name(keyword, name)
|
78
|
-
raise UnNamedFeatureError.new(@current_feature.file) if name.empty?
|
79
|
-
lines = name.split(/\r?\n/)
|
80
|
-
@feature_name = lines[0]
|
81
|
-
end
|
82
|
-
|
83
|
-
def scenario_name(keyword, name, file_colon_line, source_indent)
|
84
|
-
@scenario = (name.nil? || name == "") ? "Unnamed scenario" : name.split("\n")[0]
|
85
|
-
@output = "#{keyword}: #{@scenario}\n\n"
|
86
|
-
end
|
87
|
-
|
88
|
-
def before_steps(steps)
|
89
|
-
end
|
90
|
-
|
91
|
-
def after_steps(steps)
|
92
|
-
return if @in_background || @in_examples
|
93
|
-
|
94
|
-
duration = Time.now - @steps_start
|
95
|
-
if steps.failed?
|
96
|
-
steps.each { |step| @output += "#{step.keyword}#{step.name}\n" }
|
97
|
-
@output += "\nMessage:\n"
|
98
|
-
end
|
99
|
-
build_testcase(duration, steps.status, steps.exception)
|
100
|
-
end
|
101
|
-
|
102
|
-
def before_examples(*args)
|
103
|
-
@header_row = true
|
104
|
-
@in_examples = true
|
105
|
-
end
|
57
|
+
private
|
106
58
|
|
107
|
-
def
|
108
|
-
@
|
59
|
+
def same_feature_as_previous_test_case?(feature)
|
60
|
+
@current_feature && @current_feature.file == feature.file && @current_feature.location == feature.location
|
109
61
|
end
|
110
62
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
@
|
63
|
+
def start_feature(feature)
|
64
|
+
raise UnNamedFeatureError.new(feature.file) if feature.name.empty?
|
65
|
+
@current_feature = feature
|
66
|
+
@failures = @errors = @tests = @skipped = 0
|
67
|
+
@builder = Builder::XmlMarkup.new(:indent => 2)
|
68
|
+
@time = 0
|
115
69
|
end
|
116
70
|
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
71
|
+
def end_feature
|
72
|
+
@testsuite = Builder::XmlMarkup.new(:indent => 2)
|
73
|
+
@testsuite.instruct!
|
74
|
+
@testsuite.testsuite(
|
75
|
+
:failures => @failures,
|
76
|
+
:errors => @errors,
|
77
|
+
:skipped => @skipped,
|
78
|
+
:tests => @tests,
|
79
|
+
:time => "%.6f" % @time,
|
80
|
+
:name => @current_feature.name ) do
|
81
|
+
@testsuite << @builder.target!
|
127
82
|
end
|
128
83
|
|
129
|
-
@
|
130
|
-
end
|
131
|
-
|
132
|
-
def before_test_case(test_case)
|
133
|
-
if @options[:expand] and test_case.keyword == "Scenario Outline"
|
134
|
-
@exception = nil
|
135
|
-
end
|
84
|
+
write_file(feature_result_filename(@current_feature.file), @testsuite.target!)
|
136
85
|
end
|
137
86
|
|
138
|
-
def
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
87
|
+
def create_output_string(test_case, scenario, result, row_name)
|
88
|
+
output = "#{test_case.keyword}: #{scenario}\n\n"
|
89
|
+
return output if result.ok?(@options[:strict])
|
90
|
+
if test_case.keyword == "Scenario"
|
91
|
+
output += "#{@failing_step_source.keyword}" unless hook?(@failing_step_source)
|
92
|
+
output += "#{@failing_step_source.name}\n"
|
93
|
+
else
|
94
|
+
output += "Example row: #{row_name}\n"
|
143
95
|
end
|
96
|
+
output + "\nMessage:\n"
|
144
97
|
end
|
145
98
|
|
146
|
-
def
|
147
|
-
|
148
|
-
test_case_name = NameBuilder.new(test_case)
|
149
|
-
@scenario = test_case_name.outline_name
|
150
|
-
@output = "#{test_case.keyword}: #{@scenario}\n\n"
|
151
|
-
if result.failed?
|
152
|
-
@output += "Example row: #{test_case_name.row_name}\n"
|
153
|
-
@output += "\nMessage:\n"
|
154
|
-
end
|
155
|
-
test_case_result = ResultBuilder.new(result)
|
156
|
-
build_testcase(test_case_result.test_case_duration, test_case_result.status, @exception, test_case_name.name_suffix)
|
157
|
-
end
|
99
|
+
def hook?(step)
|
100
|
+
["Before hook", "After hook", "AfterStep hook"].include? step.name
|
158
101
|
end
|
159
102
|
|
160
|
-
|
161
|
-
|
162
|
-
def build_testcase(duration, status, exception = nil, suffix = "")
|
103
|
+
def build_testcase(result, scenario_designation, output)
|
104
|
+
duration = ResultBuilder.new(result).test_case_duration
|
163
105
|
@time += duration
|
164
|
-
classname = @
|
165
|
-
name =
|
166
|
-
pending = [:pending, :undefined].include?(status) && (!@options[:strict])
|
106
|
+
classname = @current_feature.name
|
107
|
+
name = scenario_designation
|
167
108
|
|
168
109
|
@builder.testcase(:classname => classname, :name => name, :time => "%.6f" % duration) do
|
169
|
-
if
|
110
|
+
if !result.passed? && result.ok?(@options[:strict])
|
170
111
|
@builder.skipped
|
171
112
|
@skipped += 1
|
172
|
-
elsif
|
173
|
-
|
174
|
-
|
113
|
+
elsif !result.passed?
|
114
|
+
status = result.to_sym
|
115
|
+
exception = get_backtrace_object(result)
|
116
|
+
@builder.failure(:message => "#{status} #{name}", :type => status) do
|
117
|
+
@builder.cdata! output
|
175
118
|
@builder.cdata!(format_exception(exception)) if exception
|
176
119
|
end
|
177
120
|
@failures += 1
|
178
121
|
end
|
179
|
-
@builder.tag!('system-out')
|
180
|
-
|
122
|
+
@builder.tag!('system-out') do
|
123
|
+
@builder.cdata! strip_control_chars(@interceptedout.buffer.join)
|
124
|
+
end
|
125
|
+
@builder.tag!('system-err') do
|
126
|
+
@builder.cdata! strip_control_chars(@interceptederr.buffer.join)
|
127
|
+
end
|
181
128
|
end
|
182
129
|
@tests += 1
|
183
130
|
end
|
184
131
|
|
132
|
+
def get_backtrace_object(result)
|
133
|
+
if result.failed?
|
134
|
+
return result.exception
|
135
|
+
elsif result.backtrace
|
136
|
+
return result
|
137
|
+
else
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
185
142
|
def format_exception(exception)
|
186
143
|
(["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
|
187
144
|
end
|
@@ -202,13 +159,15 @@ module Cucumber
|
|
202
159
|
def strip_control_chars(cdata)
|
203
160
|
cdata.scan(/[[:print:]\t\n\r]/).join
|
204
161
|
end
|
205
|
-
|
162
|
+
|
206
163
|
end
|
207
164
|
|
208
165
|
class NameBuilder
|
209
|
-
attr_reader :
|
166
|
+
attr_reader :scenario_name, :name_suffix, :row_name
|
210
167
|
|
211
168
|
def initialize(test_case)
|
169
|
+
@name_suffix = ""
|
170
|
+
@row_name = ""
|
212
171
|
test_case.describe_source_to self
|
213
172
|
end
|
214
173
|
|
@@ -216,12 +175,13 @@ module Cucumber
|
|
216
175
|
self
|
217
176
|
end
|
218
177
|
|
219
|
-
def scenario(
|
178
|
+
def scenario(scenario)
|
179
|
+
@scenario_name = (scenario.name.nil? || scenario.name == "") ? "Unnamed scenario" : scenario.name
|
220
180
|
self
|
221
181
|
end
|
222
182
|
|
223
183
|
def scenario_outline(outline)
|
224
|
-
@
|
184
|
+
@scenario_name = (outline.name.nil? || outline.name == "") ? "Unnamed scenario outline" : outline.name
|
225
185
|
self
|
226
186
|
end
|
227
187
|
|
@@ -237,37 +197,26 @@ module Cucumber
|
|
237
197
|
end
|
238
198
|
|
239
199
|
class ResultBuilder
|
240
|
-
attr_reader :
|
200
|
+
attr_reader :test_case_duration
|
241
201
|
def initialize(result)
|
242
202
|
@test_case_duration = 0
|
243
203
|
result.describe_to(self)
|
244
204
|
end
|
245
205
|
|
246
|
-
def passed
|
247
|
-
@status = :passed
|
248
|
-
end
|
206
|
+
def passed(*) end
|
249
207
|
|
250
|
-
def failed
|
251
|
-
@status = :failed
|
252
|
-
end
|
208
|
+
def failed(*) end
|
253
209
|
|
254
|
-
def undefined
|
255
|
-
@status = :undefined
|
256
|
-
end
|
210
|
+
def undefined(*) end
|
257
211
|
|
258
|
-
def skipped
|
259
|
-
@status = :skipped
|
260
|
-
end
|
212
|
+
def skipped(*) end
|
261
213
|
|
262
|
-
def pending(*)
|
263
|
-
@status = :pending
|
264
|
-
end
|
214
|
+
def pending(*) end
|
265
215
|
|
266
|
-
def exception(*)
|
267
|
-
end
|
216
|
+
def exception(*) end
|
268
217
|
|
269
218
|
def duration(duration, *)
|
270
|
-
duration.tap { |duration| @test_case_duration = duration.nanoseconds / 10
|
219
|
+
duration.tap { |duration| @test_case_duration = duration.nanoseconds / 10**9.0 }
|
271
220
|
end
|
272
221
|
end
|
273
222
|
|
@@ -2,6 +2,7 @@ require 'forwardable'
|
|
2
2
|
require 'delegate'
|
3
3
|
require 'cucumber/errors'
|
4
4
|
require 'cucumber/multiline_argument'
|
5
|
+
require 'cucumber/formatter/backtrace_filter'
|
5
6
|
require 'cucumber/formatter/legacy_api/ast'
|
6
7
|
|
7
8
|
module Cucumber
|
@@ -29,13 +30,13 @@ module Cucumber
|
|
29
30
|
|
30
31
|
def after_test_step(test_step, result)
|
31
32
|
printer.after_test_step(test_step, result)
|
32
|
-
formatter.after_test_step(test_step, result)
|
33
|
+
formatter.after_test_step(test_step, result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter))
|
33
34
|
end
|
34
35
|
|
35
36
|
def after_test_case(test_case, result)
|
36
37
|
record_test_case_result(test_case, result)
|
37
38
|
printer.after_test_case(test_case, result)
|
38
|
-
formatter.after_test_case(test_case, result)
|
39
|
+
formatter.after_test_case(test_case, result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter))
|
39
40
|
end
|
40
41
|
|
41
42
|
def puts(*messages)
|
@@ -271,7 +272,7 @@ module Cucumber
|
|
271
272
|
|
272
273
|
def after_step_hook(hook, result)
|
273
274
|
p current_test_step_source if current_test_step_source.step.nil?
|
274
|
-
line =
|
275
|
+
line = current_test_step_source.step.backtrace_line
|
275
276
|
@child.after_step_hook Ast::HookResult.new(LegacyResultBuilder.new(result).
|
276
277
|
append_to_exception_backtrace(line), @delayed_messages, @delayed_embeddings)
|
277
278
|
@delayed_messages = []
|
@@ -321,7 +322,7 @@ module Cucumber
|
|
321
322
|
if same_background_as_previous_test_case?(source)
|
322
323
|
HiddenBackgroundPrinter.new(formatter, source.background)
|
323
324
|
else
|
324
|
-
BackgroundPrinter.new(formatter, source.background, before_hook_results)
|
325
|
+
BackgroundPrinter.new(formatter, node, source.background, before_hook_results)
|
325
326
|
end
|
326
327
|
elsif source.scenario
|
327
328
|
ScenarioPrinter.new(formatter, source.scenario, before_hook_results)
|
@@ -448,7 +449,7 @@ module Cucumber
|
|
448
449
|
end
|
449
450
|
end
|
450
451
|
|
451
|
-
BackgroundPrinter = Struct.new(:formatter, :node, :before_hook_results) do
|
452
|
+
BackgroundPrinter = Struct.new(:formatter, :feature, :node, :before_hook_results) do
|
452
453
|
|
453
454
|
def after_test_case(*)
|
454
455
|
end
|
@@ -457,7 +458,8 @@ module Cucumber
|
|
457
458
|
end
|
458
459
|
|
459
460
|
def before
|
460
|
-
formatter.before_background node
|
461
|
+
formatter.before_background Ast::Background.new(feature, node)
|
462
|
+
Ast::Comments.new(node.comments).accept(formatter)
|
461
463
|
formatter.background_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
|
462
464
|
before_hook_results.accept(formatter)
|
463
465
|
self
|
@@ -477,7 +479,7 @@ module Cucumber
|
|
477
479
|
|
478
480
|
def after
|
479
481
|
@child.after if @child
|
480
|
-
formatter.after_background(node)
|
482
|
+
formatter.after_background(Ast::Background.new(feature, node))
|
481
483
|
self
|
482
484
|
end
|
483
485
|
|
@@ -519,6 +521,7 @@ module Cucumber
|
|
519
521
|
|
520
522
|
def before
|
521
523
|
formatter.before_feature_element(node)
|
524
|
+
Ast::Comments.new(node.comments).accept(formatter)
|
522
525
|
Ast::Tags.new(node.tags).accept(formatter)
|
523
526
|
formatter.scenario_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
|
524
527
|
before_hook_results.accept(formatter)
|
@@ -593,6 +596,7 @@ module Cucumber
|
|
593
596
|
|
594
597
|
def before
|
595
598
|
formatter.before_feature_element(node)
|
599
|
+
Ast::Comments.new(node.comments).accept(formatter)
|
596
600
|
Ast::Tags.new(node.tags).accept(formatter)
|
597
601
|
formatter.scenario_name node.keyword, node.legacy_conflated_name_and_description, node.location.to_s, indent.of(node)
|
598
602
|
OutlineStepsPrinter.new(formatter, configuration, indent).print(node)
|
@@ -693,6 +697,8 @@ module Cucumber
|
|
693
697
|
|
694
698
|
def before
|
695
699
|
formatter.before_examples(node)
|
700
|
+
Ast::Comments.new(node.comments).accept(formatter)
|
701
|
+
Ast::Tags.new(node.tags).accept(formatter)
|
696
702
|
formatter.examples_name(node.keyword, node.legacy_conflated_name_and_description)
|
697
703
|
formatter.before_outline_table(legacy_table)
|
698
704
|
if !configuration.expand?
|
@@ -803,6 +809,7 @@ module Cucumber
|
|
803
809
|
end
|
804
810
|
|
805
811
|
def before
|
812
|
+
Ast::Comments.new(node.comments).accept(formatter)
|
806
813
|
formatter.before_table_row(node)
|
807
814
|
self
|
808
815
|
end
|
@@ -822,6 +829,7 @@ module Cucumber
|
|
822
829
|
class TableRowPrinter < TableRowPrinterBase
|
823
830
|
def before
|
824
831
|
before_hook_results.accept(formatter)
|
832
|
+
Ast::Comments.new(node.comments).accept(formatter)
|
825
833
|
formatter.before_table_row(node)
|
826
834
|
self
|
827
835
|
end
|
@@ -995,66 +1003,22 @@ module Cucumber
|
|
995
1003
|
return filtered_step_exception(step) if @exception
|
996
1004
|
return nil unless @status == :undefined && configuration.strict?
|
997
1005
|
@exception = Cucumber::Undefined.from(@result, step.name)
|
1006
|
+
@exception.backtrace << step.backtrace_line
|
998
1007
|
filtered_step_exception(step)
|
999
1008
|
end
|
1000
1009
|
|
1001
1010
|
def filtered_exception
|
1002
|
-
BacktraceFilter.new(@exception.dup).exception
|
1011
|
+
Cucumber::Formatter::BacktraceFilter.new(@exception.dup).exception
|
1003
1012
|
end
|
1004
1013
|
|
1005
1014
|
def filtered_step_exception(step)
|
1006
1015
|
exception = filtered_exception
|
1007
|
-
|
1008
|
-
return BacktraceFilter.new(exception).exception
|
1016
|
+
return Cucumber::Formatter::BacktraceFilter.new(exception).exception
|
1009
1017
|
end
|
1010
1018
|
end
|
1011
1019
|
|
1012
1020
|
end
|
1013
1021
|
|
1014
|
-
class StepBacktraceLine < Struct.new(:step)
|
1015
|
-
def initialize(step)
|
1016
|
-
raise ArgumentError if step.nil?
|
1017
|
-
super
|
1018
|
-
end
|
1019
|
-
|
1020
|
-
def to_s
|
1021
|
-
step.backtrace_line
|
1022
|
-
end
|
1023
|
-
end
|
1024
|
-
|
1025
|
-
require 'cucumber/platform'
|
1026
|
-
class BacktraceFilter
|
1027
|
-
BACKTRACE_FILTER_PATTERNS = \
|
1028
|
-
[/vendor\/rails|lib\/cucumber|bin\/cucumber:|lib\/rspec|gems\/|minitest|test\/unit|.gem\/ruby|lib\/ruby/]
|
1029
|
-
if(::Cucumber::JRUBY)
|
1030
|
-
BACKTRACE_FILTER_PATTERNS << /org\/jruby/
|
1031
|
-
end
|
1032
|
-
PWD_PATTERN = /#{::Regexp.escape(::Dir.pwd)}\//m
|
1033
|
-
|
1034
|
-
def initialize(exception)
|
1035
|
-
@exception = exception
|
1036
|
-
end
|
1037
|
-
|
1038
|
-
def exception
|
1039
|
-
return @exception if ::Cucumber.use_full_backtrace
|
1040
|
-
@exception.backtrace.each{|line| line.gsub!(PWD_PATTERN, "./")}
|
1041
|
-
|
1042
|
-
filtered = (@exception.backtrace || []).reject do |line|
|
1043
|
-
BACKTRACE_FILTER_PATTERNS.detect { |p| line =~ p }
|
1044
|
-
end
|
1045
|
-
|
1046
|
-
if ::ENV['CUCUMBER_TRUNCATE_OUTPUT']
|
1047
|
-
# Strip off file locations
|
1048
|
-
filtered = filtered.map do |line|
|
1049
|
-
line =~ /(.*):in `/ ? $1 : line
|
1050
|
-
end
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
@exception.set_backtrace(filtered)
|
1054
|
-
@exception
|
1055
|
-
end
|
1056
|
-
end
|
1057
|
-
|
1058
1022
|
end
|
1059
1023
|
end
|
1060
1024
|
end
|