cucumber 2.0.0 → 2.0.1
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/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
|