aslakhellesoy-cucumber 0.3.102.2 → 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 +5 -2
- data/Manifest.txt +2 -0
- 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/lib/cucumber/ast.rb +1 -0
- data/lib/cucumber/ast/table.rb +4 -4
- 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/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 +2 -3
- data/lib/cucumber/formatter/tag_cloud.rb +7 -6
- data/lib/cucumber/formatter/usage.rb +4 -7
- data/lib/cucumber/version.rb +2 -2
- 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/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
- metadata +1 -1
    
        data/History.txt
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            ==  | 
| 1 | 
            +
            == 2009-09-24
         | 
| 2 2 |  | 
| 3 3 | 
             
            This release gives you back some of the control over the Rails environment that was accidentally taken away from you in the 
         | 
| 4 4 | 
             
            previous release.
         | 
| @@ -6,13 +6,16 @@ previous release. | |
| 6 6 | 
             
            Using this release on a Rails project requires a rerun of script/generate cucumber.
         | 
| 7 7 |  | 
| 8 8 | 
             
            === New Features
         | 
| 9 | 
            -
            * Added a new @no-txn tag to selectively turn off transactions for a  | 
| 9 | 
            +
            * Added a new @no-txn tag to selectively turn off transactions for a particlular scenario.
         | 
| 10 10 | 
             
            * Added back a way to globally turn off transactions.
         | 
| 11 11 | 
             
            * Renamed @allow_rescue tag to @allow-rescue.
         | 
| 12 12 |  | 
| 13 13 | 
             
            === Bugfixes
         | 
| 14 14 | 
             
            * Gracefully handle cases when optional regexp groups are not matched. Ex: /should( not)? be flashed '([^']*?)'$/ (Aslak Hellesøy)
         | 
| 15 15 |  | 
| 16 | 
            +
            === Changed Features
         | 
| 17 | 
            +
            * The Formatter API has completely changed. Formatters are no longer a double-dispacth visitor - just a single-dispatch listener (#438 Matt Wynne)
         | 
| 18 | 
            +
             | 
| 16 19 | 
             
            == 2009-09-22
         | 
| 17 20 |  | 
| 18 21 | 
             
            This release has some changes in the Rails support, so make sure you run "script/generate cucumber" after you upgrade.
         | 
    
        data/Manifest.txt
    CHANGED
    
    | @@ -329,6 +329,7 @@ lib/cucumber/ast/step_collection.rb | |
| 329 329 | 
             
            lib/cucumber/ast/step_invocation.rb
         | 
| 330 330 | 
             
            lib/cucumber/ast/table.rb
         | 
| 331 331 | 
             
            lib/cucumber/ast/tags.rb
         | 
| 332 | 
            +
            lib/cucumber/ast/tree_walker.rb
         | 
| 332 333 | 
             
            lib/cucumber/ast/visitor.rb
         | 
| 333 334 | 
             
            lib/cucumber/broadcaster.rb
         | 
| 334 335 | 
             
            lib/cucumber/cli/configuration.rb
         | 
| @@ -421,6 +422,7 @@ spec/cucumber/ast/scenario_spec.rb | |
| 421 422 | 
             
            spec/cucumber/ast/step_collection_spec.rb
         | 
| 422 423 | 
             
            spec/cucumber/ast/step_spec.rb
         | 
| 423 424 | 
             
            spec/cucumber/ast/table_spec.rb
         | 
| 425 | 
            +
            spec/cucumber/ast/tree_walker_spec.rb
         | 
| 424 426 | 
             
            spec/cucumber/broadcaster_spec.rb
         | 
| 425 427 | 
             
            spec/cucumber/cli/configuration_spec.rb
         | 
| 426 428 | 
             
            spec/cucumber/cli/drb_client_spec.rb
         | 
| @@ -8,7 +8,7 @@ Feature: Custom Formatter | |
| 8 8 | 
             
                  | 1           | 1                                    | 1     | 1     | 1    | 2            | 1           | 2             | 1           | 2      | 1    |
         | 
| 9 9 |  | 
| 10 10 | 
             
                  """
         | 
| 11 | 
            -
             | 
| 11 | 
            +
             | 
| 12 12 | 
             
                Scenario: my own formatter
         | 
| 13 13 | 
             
                  Given a standard Cucumber project directory structure
         | 
| 14 14 | 
             
                  And a file named "features/f.feature" with:
         | 
| @@ -25,13 +25,13 @@ Feature: Custom Formatter | |
| 25 25 | 
             
                  And a file named "features/support/ze/formator.rb" with:
         | 
| 26 26 | 
             
                    """
         | 
| 27 27 | 
             
                    module Ze
         | 
| 28 | 
            -
                      class Formator | 
| 28 | 
            +
                      class Formator
         | 
| 29 29 | 
             
                        def initialize(step_mother, io, options)
         | 
| 30 | 
            -
                           | 
| 30 | 
            +
                          @step_mother = step_mother
         | 
| 31 31 | 
             
                          @io = io
         | 
| 32 32 | 
             
                        end
         | 
| 33 33 |  | 
| 34 | 
            -
                        def  | 
| 34 | 
            +
                        def scenario_name(keyword, name, file_colon_line, source_indent)
         | 
| 35 35 | 
             
                          @io.puts "$ #{name.upcase}"
         | 
| 36 36 | 
             
                        end
         | 
| 37 37 | 
             
                      end
         | 
    
        data/lib/cucumber/ast.rb
    CHANGED
    
    | @@ -13,6 +13,7 @@ require 'cucumber/ast/py_string' | |
| 13 13 | 
             
            require 'cucumber/ast/outline_table'
         | 
| 14 14 | 
             
            require 'cucumber/ast/examples'
         | 
| 15 15 | 
             
            require 'cucumber/ast/visitor'
         | 
| 16 | 
            +
            require 'cucumber/ast/tree_walker'
         | 
| 16 17 |  | 
| 17 18 | 
             
            module Cucumber
         | 
| 18 19 | 
             
              # Classes in this module represent the Abstract Syntax Tree (AST)
         | 
    
        data/lib/cucumber/ast/table.rb
    CHANGED
    
    | @@ -389,11 +389,11 @@ module Cucumber | |
| 389 389 |  | 
| 390 390 | 
             
                    c = Term::ANSIColor.coloring?
         | 
| 391 391 | 
             
                    Term::ANSIColor.coloring = options[:color]
         | 
| 392 | 
            -
                     | 
| 393 | 
            -
                     | 
| 394 | 
            -
                     | 
| 392 | 
            +
                    formatter = Formatter::Pretty.new(nil, io, options)
         | 
| 393 | 
            +
                    formatter.instance_variable_set('@indent', options[:indent])
         | 
| 394 | 
            +
                    TreeWalker.new(nil, [formatter]).visit_multiline_arg(self)
         | 
| 395 | 
            +
                    
         | 
| 395 396 | 
             
                    Term::ANSIColor.coloring = c
         | 
| 396 | 
            -
             | 
| 397 397 | 
             
                    io.rewind
         | 
| 398 398 | 
             
                    s = "\n" + io.read + (" " * (options[:indent] - 2))
         | 
| 399 399 | 
             
                    s
         | 
    
        data/lib/cucumber/ast/visitor.rb
    CHANGED
    
    | @@ -1,115 +1,11 @@ | |
| 1 1 | 
             
            module Cucumber
         | 
| 2 2 | 
             
              module Ast
         | 
| 3 | 
            -
                # Base class for formatters. This class just walks the tree depth first.
         | 
| 4 | 
            -
                # Just override the methods you care about. Remember to call super if you
         | 
| 5 | 
            -
                # override a method.
         | 
| 6 3 | 
             
                class Visitor
         | 
| 7 | 
            -
                   | 
| 8 | 
            -
                  attr_reader :step_mother #:nodoc:
         | 
| 4 | 
            +
                  DEPRECATION_WARNING = "Cucumber::Ast::Visitor is deprecated and will be removed. You no longer need to inherit from this class."
         | 
| 9 5 |  | 
| 10 6 | 
             
                  def initialize(step_mother)
         | 
| 11 | 
            -
                     | 
| 12 | 
            -
                    @step_mother = step_mother
         | 
| 7 | 
            +
                    raise(DEPRECATION_WARNING)
         | 
| 13 8 | 
             
                  end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                  def visit_features(features)
         | 
| 16 | 
            -
                    features.accept(self)
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  def visit_feature(feature)
         | 
| 20 | 
            -
                    feature.accept(self)
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                  def visit_comment(comment)
         | 
| 24 | 
            -
                    comment.accept(self)
         | 
| 25 | 
            -
                  end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                  def visit_comment_line(comment_line)
         | 
| 28 | 
            -
                  end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                  def visit_tags(tags)
         | 
| 31 | 
            -
                    tags.accept(self)
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                  def visit_tag_name(tag_name)
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                  def visit_feature_name(name)
         | 
| 38 | 
            -
                  end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                  # +feature_element+ is either Scenario or ScenarioOutline
         | 
| 41 | 
            -
                  def visit_feature_element(feature_element)
         | 
| 42 | 
            -
                    feature_element.accept(self)
         | 
| 43 | 
            -
                  end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                  def visit_background(background)
         | 
| 46 | 
            -
                    background.accept(self)
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                  def visit_background_name(keyword, name, file_colon_line, source_indent)
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  def visit_examples_array(examples_array)
         | 
| 53 | 
            -
                    examples_array.accept(self)
         | 
| 54 | 
            -
                  end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                  def visit_examples(examples)
         | 
| 57 | 
            -
                    examples.accept(self)
         | 
| 58 | 
            -
                  end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                  def visit_examples_name(keyword, name)
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                  def visit_outline_table(outline_table)
         | 
| 64 | 
            -
                    @table = outline_table
         | 
| 65 | 
            -
                    outline_table.accept(self)
         | 
| 66 | 
            -
                  end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                  def visit_scenario_name(keyword, name, file_colon_line, source_indent)
         | 
| 69 | 
            -
                  end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                  def visit_steps(steps)
         | 
| 72 | 
            -
                    steps.accept(self)
         | 
| 73 | 
            -
                  end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  def visit_step(step)
         | 
| 76 | 
            -
                    step.accept(self)
         | 
| 77 | 
            -
                  end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                  def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
         | 
| 80 | 
            -
                    visit_step_name(keyword, step_match, status, source_indent, background)
         | 
| 81 | 
            -
                    visit_multiline_arg(multiline_arg) if multiline_arg
         | 
| 82 | 
            -
                    visit_exception(exception, status) if exception
         | 
| 83 | 
            -
                  end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                  def visit_step_name(keyword, step_match, status, source_indent, background) #:nodoc:
         | 
| 86 | 
            -
                  end
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  def visit_multiline_arg(multiline_arg) #:nodoc:
         | 
| 89 | 
            -
                    multiline_arg.accept(self)
         | 
| 90 | 
            -
                  end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                  def visit_exception(exception, status) #:nodoc:
         | 
| 93 | 
            -
                  end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                  def visit_py_string(string)
         | 
| 96 | 
            -
                  end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                  def visit_table_row(table_row)
         | 
| 99 | 
            -
                    table_row.accept(self)
         | 
| 100 | 
            -
                  end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                  def visit_table_cell(table_cell)
         | 
| 103 | 
            -
                    table_cell.accept(self)
         | 
| 104 | 
            -
                  end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                  def visit_table_cell_value(value, status)
         | 
| 107 | 
            -
                  end
         | 
| 108 | 
            -
             | 
| 109 | 
            -
                  # Print +announcement+. This method can be called from within StepDefinitions.
         | 
| 110 | 
            -
                  def announce(announcement)
         | 
| 111 | 
            -
                  end
         | 
| 112 | 
            -
             | 
| 113 9 | 
             
                end
         | 
| 114 10 | 
             
              end
         | 
| 115 11 | 
             
            end
         | 
| @@ -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
         | 
| @@ -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
         |