cucumber 0.3.102 → 0.3.103
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.
- data/History.txt +18 -0
- data/Manifest.txt +6 -2
- data/examples/java/README.textile +3 -3
- data/examples/self_test/features/sample.feature +1 -1
- data/examples/self_test/features/search_sample.feature +1 -1
- data/features/custom_formatter.feature +4 -4
- data/features/steps_formatter.feature +2 -1
- data/lib/cucumber/ast.rb +1 -0
- data/lib/cucumber/ast/table.rb +4 -4
- data/lib/cucumber/ast/tree_walker.rb +185 -0
- data/lib/cucumber/ast/visitor.rb +2 -106
- data/lib/cucumber/cli/configuration.rb +28 -28
- data/lib/cucumber/cli/language_help_formatter.rb +5 -7
- data/lib/cucumber/cli/main.rb +3 -3
- data/lib/cucumber/core_ext/string.rb +0 -22
- data/lib/cucumber/formatter/html.rb +203 -113
- data/lib/cucumber/formatter/junit.rb +29 -23
- data/lib/cucumber/formatter/pdf.rb +74 -69
- data/lib/cucumber/formatter/pretty.rb +93 -78
- data/lib/cucumber/formatter/profile.rb +2 -2
- data/lib/cucumber/formatter/progress.rb +16 -10
- data/lib/cucumber/formatter/rerun.rb +4 -5
- data/lib/cucumber/formatter/steps.rb +6 -7
- data/lib/cucumber/formatter/tag_cloud.rb +7 -6
- data/lib/cucumber/formatter/usage.rb +7 -10
- data/lib/cucumber/language_support/step_definition_methods.rb +4 -4
- data/lib/cucumber/rails/action_controller.rb +1 -1
- data/lib/cucumber/rails/active_record.rb +27 -14
- data/lib/cucumber/rb_support/rb_language.rb +5 -0
- data/lib/cucumber/rb_support/rb_step_definition.rb +9 -16
- data/lib/cucumber/rb_support/regexp_argument_matcher.rb +21 -0
- data/lib/cucumber/step_argument.rb +9 -0
- data/lib/cucumber/step_match.rb +24 -5
- data/lib/cucumber/version.rb +1 -1
- data/rails_generators/cucumber/templates/env.rb +14 -0
- data/spec/cucumber/ast/background_spec.rb +1 -2
- data/spec/cucumber/ast/scenario_outline_spec.rb +3 -2
- data/spec/cucumber/ast/scenario_spec.rb +1 -1
- data/spec/cucumber/ast/tree_walker_spec.rb +18 -0
- data/spec/cucumber/formatter/html_spec.rb +221 -2
- data/spec/cucumber/formatter/progress_spec.rb +9 -4
- data/spec/cucumber/parser/feature_parser_spec.rb +31 -27
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +18 -0
- data/spec/cucumber/step_match_spec.rb +40 -0
- metadata +8 -4
- data/lib/cucumber/rb_support/rb_group.rb +0 -11
- data/spec/cucumber/core_ext/string_spec.rb +0 -41
@@ -57,34 +57,9 @@ module Cucumber
|
|
57
57
|
def drb_port
|
58
58
|
@options[:drb_port].to_i if @options[:drb_port]
|
59
59
|
end
|
60
|
-
|
61
|
-
def
|
62
|
-
|
63
|
-
formatters = @options[:formats].map do |format_and_out|
|
64
|
-
format = format_and_out[0]
|
65
|
-
out = format_and_out[1]
|
66
|
-
if String === out # file name
|
67
|
-
unless File.directory?(out)
|
68
|
-
out = File.open(out, Cucumber.file_mode('w'))
|
69
|
-
at_exit do
|
70
|
-
out.flush
|
71
|
-
out.close
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
begin
|
77
|
-
formatter_class = formatter_class(format)
|
78
|
-
formatter_class.new(step_mother, out, @options)
|
79
|
-
rescue Exception => e
|
80
|
-
e.message << "\nError creating formatter: #{format}"
|
81
|
-
raise e
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
broadcaster = Broadcaster.new(formatters)
|
86
|
-
broadcaster.options = @options
|
87
|
-
return broadcaster
|
60
|
+
|
61
|
+
def build_runner(step_mother, io)
|
62
|
+
Ast::TreeWalker.new(step_mother, formatters(step_mother), @options, io)
|
88
63
|
end
|
89
64
|
|
90
65
|
def formatter_class(format)
|
@@ -150,6 +125,31 @@ module Cucumber
|
|
150
125
|
end
|
151
126
|
|
152
127
|
private
|
128
|
+
|
129
|
+
def formatters(step_mother)
|
130
|
+
return [Formatter::Pretty.new(step_mother, nil, @options)] if @options[:autoformat]
|
131
|
+
@options[:formats].map do |format_and_out|
|
132
|
+
format = format_and_out[0]
|
133
|
+
out = format_and_out[1]
|
134
|
+
if String === out # file name
|
135
|
+
unless File.directory?(out)
|
136
|
+
out = File.open(out, Cucumber.file_mode('w'))
|
137
|
+
at_exit do
|
138
|
+
out.flush
|
139
|
+
out.close
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
begin
|
145
|
+
formatter_class = formatter_class(format)
|
146
|
+
formatter_class.new(step_mother, out, @options)
|
147
|
+
rescue Exception => e
|
148
|
+
e.message << "\nError creating formatter: #{format}"
|
149
|
+
raise e
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
153
|
|
154
154
|
class LogFormatter < ::Logger::Formatter
|
155
155
|
def call(severity, time, progname, msg)
|
@@ -19,7 +19,8 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
|
|
19
19
|
[lang, Cucumber::LANGUAGES[lang]['name'], Cucumber::LANGUAGES[lang]['native']]
|
20
20
|
end
|
21
21
|
table = Ast::Table.new(raw)
|
22
|
-
new(nil, io, {:check_lang=>true})
|
22
|
+
formatter = new(nil, io, {:check_lang=>true})
|
23
|
+
Ast::TreeWalker.new(nil, [formatter]).visit_multiline_arg(table)
|
23
24
|
end
|
24
25
|
|
25
26
|
def self.list_keywords(io, lang)
|
@@ -31,19 +32,17 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
|
|
31
32
|
new(nil, io, {:incomplete => language.incomplete?}).visit_multiline_arg(table)
|
32
33
|
end
|
33
34
|
|
34
|
-
def
|
35
|
+
def before_visit_multiline_arg(table)
|
35
36
|
if @options[:incomplete]
|
36
37
|
@io.puts(format_string(INCOMPLETE, :failed))
|
37
38
|
end
|
38
|
-
super
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
41
|
+
def before_visit_table_row(table_row)
|
42
42
|
@col = 1
|
43
|
-
super
|
44
43
|
end
|
45
44
|
|
46
|
-
def
|
45
|
+
def before_visit_table_cell_value(value, status)
|
47
46
|
if @col == 1
|
48
47
|
if(@options[:check_lang])
|
49
48
|
@incomplete = Parser::NaturalLanguage.get(nil, value).incomplete?
|
@@ -54,7 +53,6 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
|
|
54
53
|
end
|
55
54
|
|
56
55
|
@col += 1
|
57
|
-
super(value, status)
|
58
56
|
end
|
59
57
|
end
|
60
58
|
end
|
data/lib/cucumber/cli/main.rb
CHANGED
@@ -50,9 +50,9 @@ module Cucumber
|
|
50
50
|
|
51
51
|
enable_diffing
|
52
52
|
|
53
|
-
|
54
|
-
step_mother.visitor =
|
55
|
-
|
53
|
+
runner = configuration.build_runner(step_mother, @out_stream)
|
54
|
+
step_mother.visitor = runner # Needed to support World#announce
|
55
|
+
runner.visit_features(features)
|
56
56
|
|
57
57
|
failure = if exceeded_tag_limts?(features)
|
58
58
|
FAILURE
|
@@ -7,28 +7,6 @@ class String #:nodoc:
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
# TODO: Move to StepMatch
|
11
|
-
# +groups+ is an array of 2-element arrays, where
|
12
|
-
# the 1st element is the value of a regexp match group,
|
13
|
-
# and the 2nd element is its start index.
|
14
|
-
def gzub(groups, format=nil, &proc)
|
15
|
-
s = dup
|
16
|
-
offset = 0
|
17
|
-
groups.each do |group|
|
18
|
-
replacement = if block_given?
|
19
|
-
proc.call(group.val)
|
20
|
-
elsif Proc === format
|
21
|
-
format.call(group.val)
|
22
|
-
else
|
23
|
-
format % group.val
|
24
|
-
end
|
25
|
-
|
26
|
-
s[group.start + offset, group.val.length] = replacement
|
27
|
-
offset += replacement.length - group.val.length
|
28
|
-
end
|
29
|
-
s
|
30
|
-
end
|
31
|
-
|
32
10
|
if (Cucumber::JRUBY && Cucumber::RAILS) || Cucumber::RUBY_1_9
|
33
11
|
# Workaround for http://tinyurl.com/55uu3u
|
34
12
|
alias jlength length
|
@@ -1,214 +1,278 @@
|
|
1
1
|
require 'cucumber/formatter/ordered_xml_markup'
|
2
2
|
require 'cucumber/formatter/duration'
|
3
|
+
require 'xml'
|
4
|
+
require 'ruby-debug'
|
3
5
|
|
4
6
|
module Cucumber
|
5
7
|
module Formatter
|
6
8
|
# The formatter used for <tt>--format html</tt>
|
7
|
-
class Html
|
9
|
+
class Html
|
8
10
|
include ERB::Util # for the #h method
|
9
11
|
include Duration
|
10
12
|
|
11
13
|
def initialize(step_mother, io, options)
|
12
|
-
|
14
|
+
@io = io
|
13
15
|
@options = options
|
14
|
-
@
|
16
|
+
@buffer = {}
|
17
|
+
@current_builder = create_builder(@io)
|
15
18
|
end
|
16
19
|
|
17
|
-
def
|
18
|
-
|
20
|
+
def before_features(features)
|
21
|
+
start_buffering :features
|
19
22
|
end
|
20
23
|
|
21
|
-
def
|
24
|
+
def after_features(features)
|
25
|
+
stop_buffering :features
|
22
26
|
# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
23
|
-
|
27
|
+
builder.declare!(
|
24
28
|
:DOCTYPE,
|
25
29
|
:html,
|
26
30
|
:PUBLIC,
|
27
31
|
'-//W3C//DTD XHTML 1.0 Strict//EN',
|
28
32
|
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
|
29
33
|
)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
builder.html(:xmlns => 'http://www.w3.org/1999/xhtml') do
|
35
|
+
builder.head do
|
36
|
+
builder.meta(:content => 'text/html;charset=utf-8')
|
37
|
+
builder.title 'Cucumber'
|
34
38
|
inline_css
|
35
39
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
builder.body do
|
41
|
+
builder.div(:class => 'cucumber') do
|
42
|
+
builder << buffer(:features)
|
43
|
+
builder.div(format_duration(features.duration), :class => 'duration')
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
43
47
|
end
|
44
|
-
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
+
|
49
|
+
def before_feature(feature)
|
50
|
+
start_buffering :feature
|
51
|
+
@exceptions = []
|
52
|
+
end
|
53
|
+
|
54
|
+
def after_feature(feature)
|
55
|
+
stop_buffering :feature
|
56
|
+
builder.div(:class => 'feature') do
|
57
|
+
builder << buffer(:feature)
|
48
58
|
end
|
49
59
|
end
|
50
60
|
|
51
|
-
def
|
52
|
-
|
53
|
-
@builder.br
|
61
|
+
def before_comment(comment)
|
62
|
+
start_buffering :comment
|
54
63
|
end
|
55
64
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
65
|
+
def after_comment(comment)
|
66
|
+
stop_buffering :comment
|
67
|
+
builder.pre(:class => 'comment') do
|
68
|
+
builder << buffer(:comment)
|
60
69
|
end
|
61
70
|
end
|
62
71
|
|
63
|
-
def
|
64
|
-
|
72
|
+
def comment_line(comment_line)
|
73
|
+
builder.text!(comment_line)
|
74
|
+
builder.br
|
75
|
+
end
|
76
|
+
|
77
|
+
def after_tags(tags)
|
65
78
|
@tag_spacer = nil
|
66
79
|
end
|
67
|
-
|
68
|
-
def
|
69
|
-
|
80
|
+
|
81
|
+
def tag_name(tag_name)
|
82
|
+
builder.text!(@tag_spacer) if @tag_spacer
|
70
83
|
@tag_spacer = ' '
|
71
|
-
|
84
|
+
builder.span(tag_name, :class => 'tag')
|
72
85
|
end
|
73
86
|
|
74
|
-
def
|
87
|
+
def feature_name(name)
|
75
88
|
lines = name.split(/\r?\n/)
|
76
89
|
return if lines.empty?
|
77
|
-
|
78
|
-
|
90
|
+
builder.h2 do |h2|
|
91
|
+
builder.span(lines[0], :class => 'val')
|
79
92
|
end
|
80
|
-
|
93
|
+
builder.p(:class => 'narrative') do
|
81
94
|
lines[1..-1].each do |line|
|
82
|
-
|
83
|
-
|
95
|
+
builder.text!(line.strip)
|
96
|
+
builder.br
|
84
97
|
end
|
85
98
|
end
|
86
99
|
end
|
87
100
|
|
88
|
-
def
|
89
|
-
@
|
90
|
-
|
91
|
-
|
92
|
-
|
101
|
+
def before_background(background)
|
102
|
+
@in_background = true
|
103
|
+
start_buffering :background
|
104
|
+
end
|
105
|
+
|
106
|
+
def after_background(background)
|
107
|
+
stop_buffering :background
|
108
|
+
@in_background = nil
|
109
|
+
builder.div(:class => 'background') do
|
110
|
+
builder << buffer(:background)
|
93
111
|
end
|
94
112
|
end
|
95
113
|
|
96
|
-
def
|
114
|
+
def background_name(keyword, name, file_colon_line, source_indent)
|
97
115
|
@listing_background = true
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
116
|
+
builder.h3 do |h3|
|
117
|
+
builder.span(keyword, :class => 'keyword')
|
118
|
+
builder.text!(' ')
|
119
|
+
builder.span(name, :class => 'val')
|
102
120
|
end
|
103
121
|
end
|
104
122
|
|
105
|
-
def
|
123
|
+
def before_feature_element(feature_element)
|
124
|
+
start_buffering :feature_element
|
125
|
+
end
|
126
|
+
|
127
|
+
def after_feature_element(feature_element)
|
128
|
+
stop_buffering :feature_element
|
106
129
|
css_class = {
|
107
130
|
Ast::Scenario => 'scenario',
|
108
131
|
Ast::ScenarioOutline => 'scenario outline'
|
109
132
|
}[feature_element.class]
|
110
|
-
|
111
|
-
|
133
|
+
|
134
|
+
builder.div(:class => css_class) do
|
135
|
+
builder << buffer(:feature_element)
|
112
136
|
end
|
113
137
|
@open_step_list = true
|
114
138
|
end
|
115
|
-
|
116
|
-
def
|
139
|
+
|
140
|
+
def scenario_name(keyword, name, file_colon_line, source_indent)
|
117
141
|
@listing_background = false
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
142
|
+
builder.h3 do
|
143
|
+
builder.span(keyword, :class => 'keyword')
|
144
|
+
builder.text!(' ')
|
145
|
+
builder.span(name, :class => 'val')
|
122
146
|
end
|
123
147
|
end
|
124
|
-
|
125
|
-
def
|
148
|
+
|
149
|
+
def before_outline_table(outline_table)
|
126
150
|
@outline_row = 0
|
127
|
-
|
128
|
-
|
151
|
+
start_buffering :outline_table
|
152
|
+
end
|
153
|
+
|
154
|
+
def after_outline_table(outline_table)
|
155
|
+
stop_buffering :outline_table
|
156
|
+
builder.table do
|
157
|
+
builder << buffer(:outline_table)
|
129
158
|
end
|
130
159
|
@outline_row = nil
|
131
160
|
end
|
132
161
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
162
|
+
def before_examples(examples)
|
163
|
+
start_buffering :examples
|
164
|
+
end
|
165
|
+
|
166
|
+
def after_examples(examples)
|
167
|
+
stop_buffering :examples
|
168
|
+
builder.div(:class => 'examples') do
|
169
|
+
builder << buffer(:examples)
|
136
170
|
end
|
137
171
|
end
|
138
172
|
|
139
|
-
def
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
173
|
+
def examples_name(keyword, name)
|
174
|
+
builder.h4 do
|
175
|
+
builder.span(keyword, :class => 'keyword')
|
176
|
+
builder.text!(' ')
|
177
|
+
builder.span(name, :class => 'val')
|
144
178
|
end
|
145
179
|
end
|
146
180
|
|
147
|
-
def
|
148
|
-
|
149
|
-
|
181
|
+
def before_steps(steps)
|
182
|
+
start_buffering :steps
|
183
|
+
end
|
184
|
+
|
185
|
+
def after_steps(steps)
|
186
|
+
stop_buffering :steps
|
187
|
+
builder.ol do
|
188
|
+
builder << buffer(:steps)
|
150
189
|
end
|
151
190
|
end
|
152
|
-
|
153
|
-
def
|
191
|
+
|
192
|
+
def before_step(step)
|
154
193
|
@step_id = step.dom_id
|
155
|
-
super
|
156
194
|
end
|
157
195
|
|
158
|
-
def
|
196
|
+
def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
|
197
|
+
start_buffering :step_result
|
198
|
+
@hide_this_step = false
|
159
199
|
if exception
|
160
|
-
|
200
|
+
if @exceptions.include?(exception)
|
201
|
+
@hide_this_step = true
|
202
|
+
return
|
203
|
+
end
|
161
204
|
@exceptions << exception
|
162
205
|
end
|
163
|
-
|
206
|
+
if status != :failed && @in_background ^ background
|
207
|
+
@hide_this_step = true
|
208
|
+
return
|
209
|
+
end
|
164
210
|
@status = status
|
165
|
-
|
166
|
-
|
211
|
+
end
|
212
|
+
|
213
|
+
def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
|
214
|
+
stop_buffering :step_result
|
215
|
+
return if @hide_this_step
|
216
|
+
builder.li(:id => @step_id, :class => "step #{status}") do
|
217
|
+
builder << buffer(:step_result)
|
167
218
|
end
|
168
219
|
end
|
169
220
|
|
170
|
-
def
|
221
|
+
def step_name(keyword, step_match, status, source_indent, background)
|
171
222
|
@step_matches ||= []
|
172
223
|
background_in_scenario = background && !@listing_background
|
173
224
|
@skip_step = @step_matches.index(step_match) || background_in_scenario
|
174
225
|
@step_matches << step_match
|
175
|
-
|
226
|
+
|
176
227
|
unless @skip_step
|
177
228
|
build_step(keyword, step_match, status)
|
178
229
|
end
|
179
230
|
end
|
180
231
|
|
181
|
-
def
|
182
|
-
|
232
|
+
def exception(exception, status)
|
233
|
+
return if @hide_this_step
|
234
|
+
builder.pre(format_exception(exception), :class => status)
|
235
|
+
end
|
236
|
+
|
237
|
+
def before_multiline_arg(multiline_arg)
|
238
|
+
start_buffering :multiline_arg
|
183
239
|
end
|
184
240
|
|
185
|
-
def
|
186
|
-
|
241
|
+
def after_multiline_arg(multiline_arg)
|
242
|
+
stop_buffering :multiline_arg
|
243
|
+
return if @hide_this_step || @skip_step
|
187
244
|
if Ast::Table === multiline_arg
|
188
|
-
|
189
|
-
|
245
|
+
builder.table do
|
246
|
+
builder << buffer(:multiline_arg)
|
190
247
|
end
|
191
248
|
else
|
192
|
-
|
249
|
+
builder << buffer(:multiline_arg)
|
193
250
|
end
|
194
251
|
end
|
195
252
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
253
|
+
def py_string(string)
|
254
|
+
return if @hide_this_step
|
255
|
+
builder.pre(:class => 'val') do |pre|
|
256
|
+
builder << string.gsub("\n", '
')
|
199
257
|
end
|
200
258
|
end
|
201
259
|
|
202
|
-
def
|
260
|
+
def before_table_row(table_row)
|
203
261
|
@row_id = table_row.dom_id
|
204
262
|
@col_index = 0
|
205
|
-
|
206
|
-
|
263
|
+
start_buffering :table_row
|
264
|
+
end
|
265
|
+
|
266
|
+
def after_table_row(table_row)
|
267
|
+
stop_buffering :table_row
|
268
|
+
return if @hide_this_step
|
269
|
+
builder.tr(:id => @row_id) do
|
270
|
+
builder << buffer(:table_row)
|
207
271
|
end
|
208
272
|
if table_row.exception
|
209
|
-
|
210
|
-
|
211
|
-
|
273
|
+
builder.tr do
|
274
|
+
builder.td(:colspan => @col_index.to_s, :class => 'failed') do
|
275
|
+
builder.pre do |pre|
|
212
276
|
pre << format_exception(table_row.exception)
|
213
277
|
end
|
214
278
|
end
|
@@ -217,45 +281,71 @@ module Cucumber
|
|
217
281
|
@outline_row += 1 if @outline_row
|
218
282
|
end
|
219
283
|
|
220
|
-
def
|
284
|
+
def table_cell_value(value, status)
|
285
|
+
return if @hide_this_step
|
286
|
+
|
221
287
|
cell_type = @outline_row == 0 ? :th : :td
|
222
288
|
attributes = {:id => "#{@row_id}_#{@col_index}", :class => 'val'}
|
223
289
|
attributes[:class] += " #{status}" if status
|
224
290
|
build_cell(cell_type, value, attributes)
|
225
291
|
@col_index += 1
|
226
292
|
end
|
227
|
-
|
293
|
+
|
228
294
|
def announce(announcement)
|
229
|
-
|
295
|
+
builder.pre(announcement, :class => 'announcement')
|
230
296
|
end
|
231
|
-
|
232
|
-
|
297
|
+
|
298
|
+
private
|
233
299
|
|
234
300
|
def build_step(keyword, step_match, status)
|
235
301
|
step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
302
|
+
builder.div do |div|
|
303
|
+
builder.span(keyword, :class => 'keyword')
|
304
|
+
builder.text!(' ')
|
305
|
+
builder.span(:class => 'step val') do |name|
|
240
306
|
name << h(step_name).gsub(/<span class="(.*?)">/, '<span class="\1">').gsub(/<\/span>/, '</span>')
|
241
307
|
end
|
242
308
|
end
|
243
309
|
end
|
244
|
-
|
310
|
+
|
245
311
|
def build_cell(cell_type, value, attributes)
|
246
|
-
|
312
|
+
builder.__send__(cell_type, value, attributes)
|
247
313
|
end
|
248
|
-
|
314
|
+
|
249
315
|
def inline_css
|
250
|
-
|
251
|
-
|
316
|
+
builder.style(:type => 'text/css') do
|
317
|
+
builder.text!(File.read(File.dirname(__FILE__) + '/cucumber.css'))
|
252
318
|
end
|
253
319
|
end
|
254
|
-
|
320
|
+
|
255
321
|
def format_exception(exception)
|
256
322
|
h((["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n"))
|
257
323
|
end
|
258
324
|
|
325
|
+
def builder
|
326
|
+
@current_builder
|
327
|
+
end
|
328
|
+
|
329
|
+
def buffer(label)
|
330
|
+
result = @buffer[label]
|
331
|
+
@buffer[label] = ''
|
332
|
+
result
|
333
|
+
end
|
334
|
+
|
335
|
+
def start_buffering(label)
|
336
|
+
@buffer[label] ||= ''
|
337
|
+
@parent_builder ||= {}
|
338
|
+
@parent_builder[label] = @current_builder
|
339
|
+
@current_builder = create_builder(@buffer[label])
|
340
|
+
end
|
341
|
+
|
342
|
+
def stop_buffering(label)
|
343
|
+
@current_builder = @parent_builder[label]
|
344
|
+
end
|
345
|
+
|
346
|
+
def create_builder(io)
|
347
|
+
OrderedXmlMarkup.new(:target => io, :indent => 0)
|
348
|
+
end
|
259
349
|
end
|
260
350
|
end
|
261
351
|
end
|