kosmas58-cucumber 0.1.99.23 → 0.1.100.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/History.txt +8 -23
  2. data/Manifest.txt +14 -2
  3. data/examples/i18n/en-lol/Rakefile +6 -0
  4. data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +16 -0
  5. data/examples/i18n/en-lol/features/stuffing.feature +8 -0
  6. data/examples/i18n/en-lol/features/support/env.rb +8 -0
  7. data/examples/i18n/en-lol/lib/basket.rb +12 -0
  8. data/examples/i18n/en-lol/lib/belly.rb +11 -0
  9. data/examples/i18n/et/features/jagamine.feature +9 -0
  10. data/examples/jbehave/README.textile +4 -1
  11. data/examples/jbehave/features/trading.feature +4 -0
  12. data/examples/jbehave/pom.xml +5 -0
  13. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +6 -1
  14. data/examples/selenium/features/step_definitons/search_steps.rb +13 -0
  15. data/examples/selenium/features/support/env.rb +19 -0
  16. data/examples/selenium_webrat/Rakefile +6 -0
  17. data/examples/selenium_webrat/features/search.feature +9 -0
  18. data/examples/selenium_webrat/features/step_definitons/search_steps.rb +13 -0
  19. data/examples/selenium_webrat/features/support/env.rb +41 -0
  20. data/examples/self_test/Rakefile +1 -1
  21. data/examples/self_test/features/background/failing_background.feature +1 -0
  22. data/examples/self_test/features/step_definitions/sample_steps.rb +1 -1
  23. data/examples/self_test/features/support/tag_count_formatter.rb +1 -1
  24. data/examples/tickets/Rakefile +13 -8
  25. data/examples/tickets/cucumber.yml +2 -1
  26. data/examples/tickets/features/236.feature +13 -0
  27. data/examples/tickets/features/241.feature +13 -0
  28. data/examples/tickets/features/step_definitons/tickets_steps.rb +17 -4
  29. data/examples/tickets/features/tickets.feature +1 -1
  30. data/features/background.feature +9 -11
  31. data/features/cucumber_cli.feature +24 -1
  32. data/features/cucumber_cli_outlines.feature +10 -19
  33. data/features/report_called_undefined_steps.feature +2 -0
  34. data/gem_tasks/rspec.rake +3 -2
  35. data/lib/cucumber.rb +7 -15
  36. data/lib/cucumber/ast.rb +3 -3
  37. data/lib/cucumber/ast/background.rb +28 -66
  38. data/lib/cucumber/ast/examples.rb +15 -3
  39. data/lib/cucumber/ast/feature.rb +20 -24
  40. data/lib/cucumber/ast/feature_element.rb +46 -0
  41. data/lib/cucumber/ast/features.rb +2 -21
  42. data/lib/cucumber/ast/outline_table.rb +46 -14
  43. data/lib/cucumber/ast/py_string.rb +9 -3
  44. data/lib/cucumber/ast/scenario.rb +34 -73
  45. data/lib/cucumber/ast/scenario_outline.rb +40 -42
  46. data/lib/cucumber/ast/step.rb +51 -90
  47. data/lib/cucumber/ast/step_collection.rb +66 -0
  48. data/lib/cucumber/ast/step_invocation.rb +110 -0
  49. data/lib/cucumber/ast/table.rb +41 -21
  50. data/lib/cucumber/ast/tags.rb +4 -11
  51. data/lib/cucumber/ast/visitor.rb +35 -19
  52. data/lib/cucumber/broadcaster.rb +1 -3
  53. data/lib/cucumber/cli/configuration.rb +25 -17
  54. data/lib/cucumber/cli/language_help_formatter.rb +4 -4
  55. data/lib/cucumber/cli/main.rb +6 -4
  56. data/lib/cucumber/core_ext/proc.rb +2 -2
  57. data/lib/cucumber/formatter/ansicolor.rb +0 -1
  58. data/lib/cucumber/formatter/console.rb +24 -34
  59. data/lib/cucumber/formatter/html.rb +18 -11
  60. data/lib/cucumber/formatter/pretty.rb +48 -36
  61. data/lib/cucumber/formatter/profile.rb +6 -6
  62. data/lib/cucumber/formatter/progress.rb +14 -22
  63. data/lib/cucumber/formatter/rerun.rb +6 -6
  64. data/lib/cucumber/jbehave.rb +21 -26
  65. data/lib/cucumber/languages.yml +17 -2
  66. data/lib/cucumber/parser/feature.rb +26 -29
  67. data/lib/cucumber/parser/feature.tt +17 -12
  68. data/lib/cucumber/parser/treetop_ext.rb +13 -13
  69. data/lib/cucumber/platform.rb +0 -1
  70. data/lib/cucumber/rails/world.rb +2 -2
  71. data/lib/cucumber/rake/task.rb +1 -2
  72. data/lib/cucumber/step_definition.rb +21 -12
  73. data/lib/cucumber/step_match.rb +49 -0
  74. data/lib/cucumber/step_mother.rb +100 -80
  75. data/lib/cucumber/version.rb +2 -2
  76. data/lib/cucumber/world.rb +53 -0
  77. data/rails_generators/cucumber/templates/paths.rb +1 -1
  78. data/rails_generators/cucumber/templates/webrat_steps.rb +17 -17
  79. data/rails_generators/feature/feature_generator.rb +5 -1
  80. data/rails_generators/feature/templates/steps.erb +0 -4
  81. data/spec/cucumber/ast/background_spec.rb +32 -41
  82. data/spec/cucumber/ast/feature_factory.rb +10 -1
  83. data/spec/cucumber/ast/feature_spec.rb +7 -30
  84. data/spec/cucumber/ast/py_string_spec.rb +7 -0
  85. data/spec/cucumber/ast/scenario_outline_spec.rb +3 -0
  86. data/spec/cucumber/ast/scenario_spec.rb +8 -25
  87. data/spec/cucumber/ast/step_collection_spec.rb +8 -0
  88. data/spec/cucumber/ast/step_spec.rb +49 -28
  89. data/spec/cucumber/ast/table_spec.rb +13 -3
  90. data/spec/cucumber/ast/tags_spec.rb +2 -18
  91. data/spec/cucumber/broadcaster_spec.rb +6 -5
  92. data/spec/cucumber/cli/configuration_spec.rb +7 -0
  93. data/spec/cucumber/cli/main_spec.rb +1 -1
  94. data/spec/cucumber/parser/feature_parser_spec.rb +6 -5
  95. data/spec/cucumber/step_definition_spec.rb +16 -5
  96. data/spec/cucumber/step_mother_spec.rb +6 -6
  97. data/spec/cucumber/world/pending_spec.rb +1 -1
  98. metadata +24 -5
  99. data/lib/cucumber/ast/filter.rb +0 -22
  100. data/lib/cucumber/ast/steps.rb +0 -13
@@ -11,19 +11,12 @@ module Cucumber
11
11
  @line, @tag_names = line, tag_names
12
12
  end
13
13
 
14
- def among?(tag_names)
15
- no_tags, yes_tags = tag_names.partition{|tag| tag =~ /^~/}
16
- no_tags = no_tags.map{|tag| tag[1..-1]}
17
-
18
- # Strip @
19
- yes_tags = yes_tags.map{|tag| tag =~ /^@(.*)/ ? $1 : tag}
20
- no_tags = no_tags.map{|tag| tag =~ /^@(.*)/ ? $1 : tag}
21
-
22
- (yes_tags.empty? || (@tag_names & yes_tags).any?) && (no_tags.empty? || (@tag_names & no_tags).empty?)
14
+ def has_tags?(tags)
15
+ (@tag_names & tags).any?
23
16
  end
24
17
 
25
- def at_lines?(lines)
26
- lines.empty? || lines.index(@line)
18
+ def matches_lines?(lines)
19
+ lines.index(@line)
27
20
  end
28
21
 
29
22
  def accept(visitor)
@@ -3,29 +3,35 @@ module Cucumber
3
3
  # A dumb visitor that implements the whole Visitor API and just walks the tree.
4
4
  class Visitor
5
5
  attr_accessor :options
6
+ attr_reader :step_mother
6
7
 
7
8
  def initialize(step_mother)
9
+ @options = {}
8
10
  @step_mother = step_mother
11
+ @current_feature_lines = []
9
12
  end
10
13
 
11
- def world(scenario, world = nil, &proc)
12
- @step_mother.world(scenario, world, &proc)
14
+ def current_feature_lines=(lines)
15
+ @current_feature_lines = lines
13
16
  end
14
17
 
15
- def new_world
16
- @step_mother.new_world
18
+ def matches_lines?(node)
19
+ @current_feature_lines.empty? || node.matches_lines?(@current_feature_lines)
17
20
  end
18
21
 
19
- def step_definition(step_name)
20
- @step_mother.step_definition(step_name)
22
+ def included_by_tags?(node)
23
+ tags = options[:include_tags] || []
24
+ tags.empty? || node.has_tags?(tags)
21
25
  end
22
26
 
23
- def current_feature_lines=(lines)
24
- @current_feature_lines = lines
27
+ def excluded_by_tags?(node)
28
+ tags = options[:exclude_tags] || []
29
+ tags.any? && node.has_tags?(tags)
25
30
  end
26
31
 
27
- def current_feature_lines
28
- @current_feature_lines || []
32
+ def matches_scenario_names?(node)
33
+ scenario_names = options[:scenario_names] || []
34
+ scenario_names.empty? || node.matches_scenario_names?(scenario_names)
29
35
  end
30
36
 
31
37
  def visit_features(features)
@@ -62,6 +68,9 @@ module Cucumber
62
68
  background.accept(self)
63
69
  end
64
70
 
71
+ def visit_background_name(keyword, name, file_colon_line, source_indent)
72
+ end
73
+
65
74
  def visit_examples(examples)
66
75
  examples.accept(self)
67
76
  end
@@ -70,10 +79,10 @@ module Cucumber
70
79
  end
71
80
 
72
81
  def visit_outline_table(outline_table)
73
- outline_table.accept(self, nil)
82
+ outline_table.accept(self)
74
83
  end
75
84
 
76
- def visit_scenario_name(keyword, name, file_line, source_indent)
85
+ def visit_scenario_name(keyword, name, file_colon_line, source_indent)
77
86
  end
78
87
 
79
88
  def visit_steps(steps)
@@ -84,26 +93,33 @@ module Cucumber
84
93
  step.accept(self)
85
94
  end
86
95
 
87
- def visit_step_name(keyword, step_name, status, step_definition, source_indent)
96
+ def visit_step_name(keyword, step_match, status, source_indent, background)
88
97
  end
89
98
 
90
- def visit_multiline_arg(multiline_arg, status)
91
- multiline_arg.accept(self, status)
99
+ def visit_multiline_arg(multiline_arg)
100
+ multiline_arg.accept(self)
92
101
  end
93
102
 
94
103
  def visit_py_string(string, status)
95
104
  end
96
105
 
97
- def visit_table_row(table_row, status)
98
- table_row.accept(self, status)
106
+ def visit_table_row(table_row)
107
+ table_row.accept(self)
99
108
  end
100
109
 
101
- def visit_table_cell(table_cell, status)
102
- table_cell.accept(self, status)
110
+ def visit_table_cell(table_cell)
111
+ table_cell.accept(self)
103
112
  end
104
113
 
105
114
  def visit_table_cell_value(value, width, status)
106
115
  end
116
+
117
+ def visit_exception(exception, status)
118
+ end
119
+
120
+ def announce(announcement)
121
+ end
122
+
107
123
  end
108
124
  end
109
125
  end
@@ -1,15 +1,13 @@
1
1
  module Cucumber
2
2
  class Broadcaster
3
-
4
3
  def initialize(receivers = [])
5
4
  @receivers = receivers
6
5
  end
7
6
 
8
7
  def method_missing(method_name, *args)
9
- @receivers.each do |receiver|
8
+ @receivers.map do |receiver|
10
9
  receiver.__send__(method_name, *args)
11
10
  end
12
11
  end
13
-
14
12
  end
15
13
  end
@@ -74,9 +74,9 @@ module Cucumber
74
74
  opts.on("-t TAGS", "--tags TAGS",
75
75
  "Only execute the features or scenarios with the specified tags.",
76
76
  "TAGS must be comma-separated without spaces. Prefix tags with ~ to",
77
- "exclude features or scenarios having that tag. tags can be specified",
77
+ "exclude features or scenarios having that tag. Tags can be specified",
78
78
  "with or without the @ prefix.") do |v|
79
- @options[:tags] = v.split(",")
79
+ @options[:include_tags], @options[:exclude_tags] = *parse_tags(v)
80
80
  end
81
81
  opts.on("-s SCENARIO", "--scenario SCENARIO",
82
82
  "Only execute the scenario with the given name. If this option",
@@ -125,7 +125,7 @@ module Cucumber
125
125
  opts.on("-b", "--backtrace", "Show full backtrace for all errors.") do
126
126
  Exception.cucumber_full_backtrace = true
127
127
  end
128
- opts.on("--strict", "Fail if there are any undefined steps.") do
128
+ opts.on("-S", "--strict", "Fail if there are any undefined steps.") do
129
129
  @options[:strict] = true
130
130
  end
131
131
  opts.on("-v", "--verbose", "Show the files and features loaded.") do
@@ -144,7 +144,7 @@ module Cucumber
144
144
  @out_stream.puts VERSION::STRING
145
145
  Kernel.exit
146
146
  end
147
- opts.on_tail("--help", "You're looking at it.") do
147
+ opts.on_tail("-h", "--help", "You're looking at it.") do
148
148
  @out_stream.puts opts.help
149
149
  Kernel.exit
150
150
  end
@@ -159,10 +159,6 @@ module Cucumber
159
159
  @paths += args
160
160
  end
161
161
 
162
- def ast_filter
163
- Ast::Filter.new(@options)
164
- end
165
-
166
162
  def verbose?
167
163
  @options[:verbose]
168
164
  end
@@ -190,7 +186,18 @@ module Cucumber
190
186
  Cucumber.load_language(@options[:lang])
191
187
  end
192
188
  end
193
-
189
+
190
+ def parse_tags(tag_string)
191
+ tag_names = tag_string.split(",")
192
+ excludes, includes = tag_names.partition{|tag| tag =~ /^~/}
193
+ excludes = excludes.map{|tag| tag[1..-1]}
194
+
195
+ # Strip @
196
+ includes = includes.map{|tag| tag =~ /^@(.*)/ ? $1 : tag}
197
+ excludes = excludes.map{|tag| tag =~ /^@(.*)/ ? $1 : tag}
198
+ [includes, excludes]
199
+ end
200
+
194
201
  def build_formatter_broadcaster(step_mother)
195
202
  return Formatter::Pretty.new(step_mother, nil, @options) if @options[:autoformat]
196
203
  formatters = @options[:formats].map do |format, out|
@@ -330,15 +337,16 @@ Defined profiles in cucumber.yml:
330
337
 
331
338
  def default_options
332
339
  {
333
- :strict => false,
334
- :require => nil,
335
- :lang => 'en',
336
- :dry_run => false,
337
- :formats => {},
338
- :excludes => [],
339
- :tags => [],
340
+ :strict => false,
341
+ :require => nil,
342
+ :lang => 'en',
343
+ :dry_run => false,
344
+ :formats => {},
345
+ :excludes => [],
346
+ :include_tags => [],
347
+ :exclude_tags => [],
340
348
  :scenario_names => [],
341
- :diff_enabled => true
349
+ :diff_enabled => true
342
350
  }
343
351
  end
344
352
 
@@ -18,7 +18,7 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
18
18
  [lang, Cucumber::LANGUAGES[lang]['name'], Cucumber::LANGUAGES[lang]['native']]
19
19
  end
20
20
  table = Ast::Table.new(raw)
21
- new(nil, io, {:check_lang=>true}, '').visit_multiline_arg(table, :passed)
21
+ new(nil, io, {:check_lang=>true}, '').visit_multiline_arg(table)
22
22
  end
23
23
 
24
24
  def self.list_keywords(io, lang)
@@ -26,17 +26,17 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
26
26
  [key, Cucumber::LANGUAGES[lang][key]]
27
27
  end
28
28
  table = Ast::Table.new(raw)
29
- new(nil, io, {:incomplete => Cucumber.language_incomplete?(lang)}, '').visit_multiline_arg(table, :passed)
29
+ new(nil, io, {:incomplete => Cucumber.language_incomplete?(lang)}, '').visit_multiline_arg(table)
30
30
  end
31
31
 
32
- def visit_multiline_arg(table, status)
32
+ def visit_multiline_arg(table)
33
33
  if @options[:incomplete]
34
34
  @io.puts(format_string(INCOMPLETE, :failed))
35
35
  end
36
36
  super
37
37
  end
38
38
 
39
- def visit_table_row(table_row, status)
39
+ def visit_table_row(table_row)
40
40
  @col = 1
41
41
  super
42
42
  end
@@ -44,9 +44,12 @@ module Cucumber
44
44
  features = load_plain_text_features
45
45
 
46
46
  visitor = configuration.build_formatter_broadcaster(step_mother)
47
+ step_mother.visitor = visitor # Needed to support World#announce
47
48
  visitor.visit_features(features)
48
-
49
- failure = features.steps[:failed].any? || (configuration.strict? && features.steps[:undefined].any?)
49
+
50
+ failure = step_mother.steps(:failed).any? ||
51
+ (configuration.strict? && step_mother.steps(:undefined).any?)
52
+
50
53
  Kernel.exit(failure ? 1 : 0)
51
54
  end
52
55
 
@@ -75,8 +78,7 @@ module Cucumber
75
78
  end
76
79
 
77
80
  def load_plain_text_features
78
- filter = configuration.ast_filter
79
- features = Ast::Features.new(filter)
81
+ features = Ast::Features.new
80
82
  parser = Parser::FeatureParser.new
81
83
 
82
84
  verbose_log("Features:")
@@ -3,7 +3,7 @@ class Proc
3
3
  PROC_PATTERN = /[\d\w]+@(.*):(.*)>/
4
4
 
5
5
  if Proc.new{}.to_s =~ PROC_PATTERN
6
- def to_backtrace_line(name)
6
+ def backtrace_line(name)
7
7
  "#{file_colon_line}:in `#{name}'"
8
8
  end
9
9
 
@@ -22,7 +22,7 @@ class Proc
22
22
  # This Ruby implementation doesn't implement Proc#to_s correctly
23
23
  STDERR.puts "*** THIS RUBY IMPLEMENTATION DOESN'T REPORT FILE AND LINE FOR PROCS ***"
24
24
 
25
- def to_backtrace_line
25
+ def backtrace_line
26
26
  nil
27
27
  end
28
28
 
@@ -70,7 +70,6 @@ module Cucumber
70
70
  'pending' => 'yellow',
71
71
  'failed' => 'red',
72
72
  'passed' => 'green',
73
- 'thead' => 'cyan',
74
73
  'outline' => 'cyan',
75
74
  'skipped' => 'cyan',
76
75
  'comment' => 'grey',
@@ -6,21 +6,16 @@ module Cucumber
6
6
  extend ANSIColor
7
7
  FORMATS = Hash.new{|hash, format| hash[format] = method(format).to_proc}
8
8
 
9
- def format_step(keyword, step_name, status, step_definition, source_indent)
10
- comment = if source_indent && step_definition
11
- c = (' # ' + step_definition.file_colon_line).indent(source_indent)
9
+ def format_step(keyword, step_match, status, source_indent)
10
+ comment = if source_indent
11
+ c = (' # ' + step_match.file_colon_line).indent(source_indent)
12
12
  format_string(c, :comment)
13
13
  else
14
14
  ''
15
15
  end
16
16
 
17
- begin
18
- line = keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment
19
- rescue
20
- # It didn't match. This often happens for :outline steps
21
- line = keyword + " " + step_name + comment
22
- end
23
-
17
+ format = format_for(status, :param)
18
+ line = keyword + " " + step_match.format_args(format) + comment
24
19
  format_string(line, status)
25
20
  end
26
21
 
@@ -33,13 +28,8 @@ module Cucumber
33
28
  end
34
29
  end
35
30
 
36
- def print_undefined_scenarios(features)
37
- elements = features.scenarios.select{|scenario| scenario.undefined?}
38
- print_elements(elements, :undefined, 'scenarios')
39
- end
40
-
41
- def print_steps(features, status)
42
- print_elements(features.steps[status], status, 'steps')
31
+ def print_steps(status)
32
+ print_elements(step_mother.steps(status), status, 'steps')
43
33
  end
44
34
 
45
35
  def print_elements(elements, status, kind)
@@ -51,7 +41,7 @@ module Cucumber
51
41
 
52
42
  elements.each_with_index do |element, i|
53
43
  if status == :failed
54
- print_exception(element.exception, 0)
44
+ print_exception(element.exception, status, 0)
55
45
  else
56
46
  @io.puts(format_string(element.backtrace_line, status))
57
47
  end
@@ -60,26 +50,27 @@ module Cucumber
60
50
  end
61
51
  end
62
52
 
63
- def print_counts(features)
64
- @io.puts dump_count(features.scenarios.length, "scenario")
53
+ def print_counts
54
+ @io.puts dump_count(step_mother.scenarios.length, "scenario")
65
55
 
66
56
  [:failed, :skipped, :undefined, :pending, :passed].each do |status|
67
- if features.steps[status].any?
68
- count_string = dump_count(features.steps[status].length, "step", status.to_s)
57
+ if step_mother.steps(status).any?
58
+ count_string = dump_count(step_mother.steps(status).length, "step", status.to_s)
69
59
  @io.puts format_string(count_string, status)
70
60
  @io.flush
71
61
  end
72
62
  end
73
63
  end
74
64
 
75
- def print_exception(e, indent)
76
- status = Cucumber::EXCEPTION_STATUS[e.class]
77
- @io.puts(format_string("#{e.message} (#{e.class})\n#{e.backtrace.join("\n")}".indent(indent), status))
65
+ def print_exception(e, status, indent)
66
+ if @options[:strict] || !(Undefined === e) || e.nested?
67
+ @io.puts(format_string("#{e.message} (#{e.class})\n#{e.backtrace.join("\n")}".indent(indent), status))
68
+ end
78
69
  end
79
70
 
80
- def print_snippets(features, options)
71
+ def print_snippets(options)
81
72
  return unless options[:snippets]
82
- undefined = features.steps[:undefined]
73
+ undefined = step_mother.steps(:undefined)
83
74
  return if undefined.empty?
84
75
  snippets = undefined.map do |step|
85
76
  step_name = Undefined === step.exception ? step.exception.step_name : step.name
@@ -95,15 +86,14 @@ module Cucumber
95
86
  @io.flush
96
87
  end
97
88
 
98
- private
99
-
100
- def with_color
101
- c = Term::ANSIColor.coloring?
102
- Term::ANSIColor.coloring = @io.tty?
103
- yield
104
- Term::ANSIColor.coloring = c
89
+ def announce(announcement)
90
+ @io.puts
91
+ @io.puts(format_string(announcement, :tag))
92
+ @io.flush
105
93
  end
106
94
 
95
+ private
96
+
107
97
  def dump_count(count, what, state=nil)
108
98
  [count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(" ")
109
99
  end
@@ -54,12 +54,14 @@ module Cucumber
54
54
 
55
55
  def visit_background(background)
56
56
  @builder.div(:class => 'background') do
57
- @builder.ol do
58
- super
59
- end
57
+ super
60
58
  end
61
59
  end
62
60
 
61
+ def visit_background_name(keyword, name, file_colon_line, source_indent)
62
+ @builder.h3("#{keyword} #{name}")
63
+ end
64
+
63
65
  def visit_feature_element(feature_element)
64
66
  @builder.div(:class => 'scenario') do
65
67
  super
@@ -67,7 +69,7 @@ module Cucumber
67
69
  @open_step_list = true
68
70
  end
69
71
 
70
- def visit_scenario_name(keyword, name, file_line, source_indent)
72
+ def visit_scenario_name(keyword, name, file_colon_line, source_indent)
71
73
  @builder.h3("#{keyword} #{name}")
72
74
  end
73
75
 
@@ -87,25 +89,26 @@ module Cucumber
87
89
  end
88
90
  end
89
91
 
90
- def visit_step_name(keyword, step_name, status, step_definition, source_indent)
92
+ def visit_step_name(keyword, step_match, status, source_indent, background)
93
+ step_name = step_match.format_args(lambda{|param| "<span>#{param}</span>"})
91
94
  @builder.li("#{keyword} #{step_name}", :class => status)
92
95
  end
93
96
 
94
- def visit_multiline_arg(multiline_arg, status)
97
+ def visit_multiline_arg(multiline_arg)
95
98
  if Ast::Table === multiline_arg
96
99
  @builder.table do
97
- super(multiline_arg, status)
100
+ super
98
101
  end
99
102
  else
100
103
  @builder.p do
101
- super(multiline_arg, status)
104
+ super
102
105
  end
103
106
  end
104
107
  end
105
108
 
106
- def visit_table_row(table_row, status)
109
+ def visit_table_row(table_row)
107
110
  @builder.tr do
108
- super(table_row, status)
111
+ super
109
112
  end
110
113
  end
111
114
 
@@ -113,6 +116,10 @@ module Cucumber
113
116
  @builder.td(value, :class => status)
114
117
  end
115
118
 
119
+ def announce(announcement)
120
+ @builder.pre(announcement, :class => 'announcement')
121
+ end
122
+
116
123
  private
117
124
 
118
125
  def inline_css
@@ -123,4 +130,4 @@ module Cucumber
123
130
 
124
131
  end
125
132
  end
126
- end
133
+ end