<NME> console.rb
<BEF> # frozen_string_literal: true

# rubocop:disable Metrics/ModuleLength

require 'cucumber/formatter/ansicolor'
require 'cucumber/formatter/duration'
      FORMATS = Hash.new{|hash, format| hash[format] = method(format).to_proc}

      def format_step(keyword, step_name, status, step_definition, source_indent)
        line = if step_definition # nil for :outline
          comment = if source_indent
            c = (' # ' + step_definition.file_colon_line).indent(source_indent)
            format_string(c, :comment)
          else
            ''
          end
          keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment
        else
          keyword + " " + step_name
        end
        format_string(line, status)
      end

    #
    # During output, each line is processed by passing it to the formatter Proc
    # which returns the formatted (e.g. colored) string.

    module Console
      extend ANSIColor
      include Duration

      def format_step(keyword, step_match, status, source_indent)
        comment = if source_indent
                    c = indent("# #{step_match.location}", source_indent)
                    format_string(c, :comment)
                  else
                    ''
                  end

        format = format_for(status, :param)
        line = keyword + step_match.format_args(format) + comment
        format_string(line, status)
      end

      def format_string(o, status)
        fmt = format_for(status)
        o.to_s.split("\n").map do |line|
          if Proc == fmt.class
            fmt.call(line)
          else
            fmt % line
          end
        end.join("\n")
      end

      def print_elements(elements, status, kind)
        return if elements.empty?

        element_messages = element_messages(elements, status)
        print_element_messages(element_messages, status, kind)
      end

      def print_element_messages(element_messages, status, kind)
        if element_messages.any?
          @io.puts(format_string("(::) #{status} #{kind} (::)", status))
          @io.puts
          @io.flush
        end

        element_messages.each do |message|
          @io.puts(format_string(message, status))
          @io.puts
          @io.flush
        end
      end

      def print_statistics(duration, config, counts, issues)
        if issues.any?
          @io.puts issues.to_s
          @io.puts
        end

        @io.puts counts.to_s
        @io.puts(format_duration(duration)) if duration && config.duration?

        if config.randomize?
          @io.puts
          @io.puts "Randomized with seed #{config.seed}"
        end

        @io.flush
      end

      def print_exception(e, status, indent)
        string = exception_message_string(e, indent)
        @io.puts(format_string(string, status))
      end

      def exception_message_string(e, indent_amount)
        message = "#{e.message} (#{e.class})".dup.force_encoding('UTF-8')
        message = linebreaks(message, ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)

        indent("#{message}\n#{e.backtrace.join("\n")}", indent_amount)
      end

      # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/10655
      def linebreaks(msg, max)
        return msg unless max && max > 0

        msg.gsub(/.{1,#{max}}(?:\s|\Z)/) do
          (Regexp.last_match(0) + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n")
        end.rstrip
      end

      def collect_snippet_data(test_step, ast_lookup)
        # collect snippet data for undefined steps
        keyword = ast_lookup.snippet_step_keyword(test_step)
        @snippets_input << Console::SnippetData.new(keyword, test_step)
      end

      def collect_undefined_parameter_type_names(undefined_parameter_type)
        @undefined_parameter_types << undefined_parameter_type.type_name
      end

      def print_snippets(options)
        return unless options[:snippets]

        snippet_text_proc = lambda do |step_keyword, step_name, multiline_arg|
          snippet_text(step_keyword, step_name, multiline_arg)
        end
        do_print_snippets(snippet_text_proc) unless @snippets_input.empty?

        @undefined_parameter_types.map do |type_name|
          do_print_undefined_parameter_type_snippet(type_name)
        end
      end

      def do_print_snippets(snippet_text_proc)
        snippets = @snippets_input.map do |data|
          snippet_text_proc.call(data.actual_keyword, data.step.text, data.step.multiline_arg)
        end.uniq

        text = "\nYou can implement step definitions for undefined steps with these snippets:\n\n"
        text += snippets.join("\n\n")
        @io.puts format_string(text, :undefined)

        @io.puts
        @io.flush
      end

      def print_passing_wip(config, passed_test_cases, ast_lookup)
        return unless config.wip?

        messages = passed_test_cases.map do |test_case|
          scenario_source = ast_lookup.scenario_source(test_case)
          keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword
          linebreaks("#{test_case.location.on_line(test_case.location.lines.max)}:in `#{keyword}: #{test_case.name}'", ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)
        end
        do_print_passing_wip(messages)
      end

      def do_print_passing_wip(passed_messages)
        if passed_messages.any?
          @io.puts format_string("\nThe --wip switch was used, so I didn't expect anything to pass. These scenarios passed:", :failed)
          print_element_messages(passed_messages, :passed, 'scenarios')
        else
          @io.puts format_string("\nThe --wip switch was used, so the failures were expected. All is good.\n", :passed)
        end
      end

      def attach(src, media_type)
        return unless media_type == 'text/x.cucumber.log+plain'
        return unless @io

        @io.puts
        @io.puts(format_string(src, :tag))
        @io.flush
      end

      def print_profile_information
        return if @options[:skip_profile_information] || @options[:profiles].nil? || @options[:profiles].empty?

        do_print_profile_information(@options[:profiles])
      end

      def do_print_profile_information(profiles)
        profiles_sentence = if profiles.size == 1
                              profiles.first
                            else
                              "#{profiles[0...-1].join(', ')} and #{profiles.last}"
                            end

        @io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size > 1}..."
      end

      def do_print_undefined_parameter_type_snippet(type_name)
        camelized = type_name.split(/_|-/).collect(&:capitalize).join

        @io.puts [
          "The parameter #{type_name} is not defined. You can define a new one with:",
          '',
          'ParameterType(',
          "  name:        '#{type_name}',",
          '  regexp:      /some regexp here/,',
          "  type:        #{camelized},",
          '  # The transformer takes as many arguments as there are capture groups in the regexp,',
          '  # or just one if there are none.',
          "  transformer: ->(s) { #{camelized}.new(s) }",
          ')',
          ''
        ].join("\n")
      end

      def indent(string, padding)
        if padding >= 0
          string.gsub(/^/, ' ' * padding)
        else
          string.gsub(/^ {0,#{-padding}}/, '')
        end
      end

      private

      FORMATS = Hash.new { |hash, format| hash[format] = method(format).to_proc }

      def format_for(*keys)
        key = keys.join('_').to_sym
        fmt = FORMATS[key]
        raise "No format for #{key.inspect}: #{FORMATS.inspect}" if fmt.nil?

        fmt
      end

      def element_messages(elements, status)
        elements.map do |element|
          if status == :failed
            exception_message_string(element.exception, 0)
          else
            linebreaks(element.backtrace_line, ENV['CUCUMBER_TRUNCATE_OUTPUT'].to_i)
          end
        end
      end

      def snippet_text(step_keyword, step_name, multiline_arg)
        keyword = Cucumber::Gherkin::I18n.code_keyword_for(step_keyword).strip
        config.snippet_generators.map do |generator|
          generator.call(keyword, step_name, multiline_arg, config.snippet_type)
        end.join("\n")
      end

      class SnippetData
        attr_reader :actual_keyword, :step

        def initialize(actual_keyword, step)
          @actual_keyword = actual_keyword
          @step = step
        end
      end
    end
  end
end
# rubocop:enable Metrics/ModuleLength

<MSG> Implement location comment for outline steps. Release 0.1.99.14.

<DFF> @@ -7,17 +7,20 @@ module Cucumber
       FORMATS = Hash.new{|hash, format| hash[format] = method(format).to_proc}
 
       def format_step(keyword, step_name, status, step_definition, source_indent)
-        line = if step_definition # nil for :outline
-          comment = if source_indent
-            c = (' # ' + step_definition.file_colon_line).indent(source_indent)
-            format_string(c, :comment)
-          else
-            ''
-          end
-          keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment
+        comment = if source_indent
+          c = (' # ' + step_definition.file_colon_line).indent(source_indent)
+          format_string(c, :comment)
         else
-          keyword + " " + step_name
+          ''
         end
+
+        begin
+          line = keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment
+        rescue
+          # It didn't match. This often happens for :outline steps
+          line = keyword + " " + step_name + comment
+        end
+
         format_string(line, status)
       end
 

{'commit': 'diff --git a/Manifest.txt b/Manifest.txt\nindex f9c51834..c60e1d5d 100644\n--- a/Manifest.txt\n+++ b/Manifest.txt\n@@ -117,6 +117,7 @@ examples/selenium/Rakefile\n examples/selenium/features/search.feature\n examples/selenium/features/step_definitons/stories_steps.rb\n examples/self_test/README.textile\n+examples/self_test/Rakefile\n examples/self_test/features/background/failing_background.feature\n examples/self_test/features/background/failing_background_after_success.feature\n examples/self_test/features/background/multiline_args_background.feature\n@@ -217,7 +218,6 @@ lib/cucumber/rake/task.rb\n lib/cucumber/step_definition.rb\n lib/cucumber/step_mother.rb\n lib/cucumber/version.rb\n-pom.xml\n rails_generators/cucumber/USAGE\n rails_generators/cucumber/cucumber_generator.rb\n rails_generators/cucumber/templates/cucumber\n@@ -272,4 +272,3 @@ spec/cucumber/treetop_parser/with_tags.feature\n spec/cucumber/world/pending_spec.rb\n spec/spec.opts\n spec/spec_helper.rb\n-src/main/java/cukes/Cucumber.java\ndiff --git a/cucumber.gemspec b/cucumber.gemspec\nindex 2b5b5080..d0918e25 100644\n--- a/cucumber.gemspec\n+++ b/cucumber.gemspec\n@@ -2,7 +2,7 @@\n \n Gem::Specification.new do |s|\n   s.name = %q{cucumber}\n-  s.version = "0.1.99.13"\n+  s.version = "0.1.99.14"\n \n   s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=\n   s.authors = ["Aslak Helles\\303\\270y"]\n@@ -12,7 +12,7 @@ Gem::Specification.new do |s|\n   s.email = ["aslak.hellesoy@gmail.com"]\n   s.executables = ["cucumber"]\n   s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "README.txt", "examples/i18n/ja/README.txt"]\n-  s.files = ["History.txt", "License.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/cucumber", "config/hoe.rb", "config/requirements.rb", "cucumber.yml", "examples/cs/README.textile", "examples/cs/Rakefile", "examples/cs/compile.bat", "examples/cs/features/addition.feature", "examples/cs/features/step_definitons/calculator_steps.rb", "examples/cs/src/demo/Calculator.cs", "examples/dos_line_endings/Rakefile", "examples/dos_line_endings/features/dos_line_endings.feature", "examples/i18n/README.textile", "examples/i18n/Rakefile", "examples/i18n/ar/Rakefile", "examples/i18n/ar/features/addition.feature", "examples/i18n/ar/features/step_definitons/calculator_steps.rb", "examples/i18n/ar/lib/calculator.rb", "examples/i18n/da/Rakefile", "examples/i18n/da/features/step_definitons/kalkulator_steps.rb", "examples/i18n/da/features/summering.feature", "examples/i18n/da/lib/kalkulator.rb", "examples/i18n/de/Rakefile", "examples/i18n/de/features/addition.feature", "examples/i18n/de/features/division.feature", "examples/i18n/de/features/step_definitons/calculator_steps.rb", "examples/i18n/de/lib/calculator.rb", "examples/i18n/en/Rakefile", "examples/i18n/en/features/addition.feature", "examples/i18n/en/features/division.feature", "examples/i18n/en/features/step_definitons/calculator_steps.rb", "examples/i18n/en/lib/calculator.rb", "examples/i18n/es/Rakefile", "examples/i18n/es/features/adicion.feature", "examples/i18n/es/features/step_definitons/calculador_steps.rb", "examples/i18n/es/lib/calculador.rb", "examples/i18n/et/Rakefile", "examples/i18n/et/features/liitmine.feature", "examples/i18n/et/features/step_definitions/kalkulaator_steps.rb", "examples/i18n/et/lib/kalkulaator.rb", "examples/i18n/fi/Rakefile", "examples/i18n/fi/features/jakolasku.feature", "examples/i18n/fi/features/step_definitons/laskin_steps.rb", "examples/i18n/fi/features/yhteenlasku.feature", "examples/i18n/fi/lib/laskin.rb", "examples/i18n/fr/Rakefile", "examples/i18n/fr/features/addition.feature", "examples/i18n/fr/features/step_definitions/calculatrice_steps.rb", "examples/i18n/fr/lib/calculatrice.rb", "examples/i18n/id/Rakefile", "examples/i18n/id/features/addition.feature", "examples/i18n/id/features/division.feature", "examples/i18n/id/features/step_definitons/calculator_steps.rb", "examples/i18n/id/lib/calculator.rb", "examples/i18n/it/Rakefile", "examples/i18n/it/features/somma.feature", "examples/i18n/it/features/step_definitons/calcolatrice_steps.rb", "examples/i18n/it/lib/calcolatrice.rb", "examples/i18n/ja/README.txt", "examples/i18n/ja/Rakefile", "examples/i18n/ja/features/addition.feature", "examples/i18n/ja/features/division.feature", "examples/i18n/ja/features/step_definitons/calculator_steps.rb", "examples/i18n/ja/lib/calculator.rb", "examples/i18n/ko/Rakefile", "examples/i18n/ko/features/addition.feature", "examples/i18n/ko/features/division.feature", "examples/i18n/ko/features/step_definitons/calculator_steps.rb", "examples/i18n/ko/lib/calculator.rb", "examples/i18n/lt/Rakefile", "examples/i18n/lt/features/addition.feature", "examples/i18n/lt/features/division.feature", "examples/i18n/lt/features/step_definitons/calculator_steps.rb", "examples/i18n/lt/lib/calculator.rb", "examples/i18n/no/Rakefile", "examples/i18n/no/features/step_definitons/kalkulator_steps.rb", "examples/i18n/no/features/summering.feature", "examples/i18n/no/lib/kalkulator.rb", "examples/i18n/pt/Rakefile", "examples/i18n/pt/features/adicao.feature", "examples/i18n/pt/features/step_definitions/calculadora_steps.rb", "examples/i18n/pt/lib/calculadora.rb", "examples/i18n/ro/Rakefile", "examples/i18n/ro/features/step_definitons/calculator_steps.rb", "examples/i18n/ro/features/suma.feature", "examples/i18n/ro/lib/calculator.rb", "examples/i18n/se/Rakefile", "examples/i18n/se/features/step_definitons/kalkulator_steps.rb", "examples/i18n/se/features/summering.feature", "examples/i18n/se/lib/kalkulator.rb", "examples/i18n/zh-CN/Rakefile", "examples/i18n/zh-CN/features/addition.feature", "examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb", "examples/i18n/zh-CN/lib/calculator.rb", "examples/java/README.textile", "examples/java/Rakefile", "examples/java/features/hello.feature", "examples/java/features/step_definitons/hello_steps.rb", "examples/java/features/step_definitons/tree_steps.rb", "examples/java/features/tree.feature", "examples/java/src/cucumber/demo/Hello.java", "examples/jbehave/README.textile", "examples/jbehave/features/support/env.rb", "examples/jbehave/features/trading.feature", "examples/jbehave/pom.xml", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java", "examples/selenium/Rakefile", "examples/selenium/features/search.feature", "examples/selenium/features/step_definitons/stories_steps.rb", "examples/self_test/README.textile", "examples/self_test/features/background/failing_background.feature", "examples/self_test/features/background/failing_background_after_success.feature", "examples/self_test/features/background/multiline_args_background.feature", "examples/self_test/features/background/passing_background.feature", "examples/self_test/features/background/pending_background.feature", "examples/self_test/features/background/scenario_outline_failing_background.feature", "examples/self_test/features/background/scenario_outline_passing_background.feature", "examples/self_test/features/call_undefined_step_from_step_def.feature", "examples/self_test/features/lots_of_undefined.feature", "examples/self_test/features/outline_sample.feature", "examples/self_test/features/sample.feature", "examples/self_test/features/step_definitions/sample_steps.rb", "examples/self_test/features/support/env.rb", "examples/test_unit/Rakefile", "examples/test_unit/features/step_definitions/test_unit_steps.rb", "examples/test_unit/features/test_unit.feature", "examples/tickets/Rakefile", "examples/tickets/cucumber.yml", "examples/tickets/features/172.feature", "examples/tickets/features/lib/eatting_machine.rb", "examples/tickets/features/lib/pantry.rb", "examples/tickets/features/scenario_outline.feature", "examples/tickets/features/step_definitons/scenario_outline_steps.rb", "examples/tickets/features/step_definitons/tickets_steps.rb", "examples/tickets/features/tickets.feature", "examples/watir/README.textile", "examples/watir/Rakefile", "examples/watir/features/search.feature", "examples/watir/features/step_definitons/search_steps.rb", "examples/watir/features/support/env.rb", "features/background.feature", "features/cucumber_cli.feature", "features/cucumber_cli_outlines.feature", "features/report_called_undefined_steps.feature", "features/step_definitions/cucumber_steps.rb", "features/step_definitions/extra_steps.rb", "features/support/env.rb", "gem_tasks/deployment.rake", "gem_tasks/environment.rake", "gem_tasks/features.rake", "gem_tasks/fix_cr_lf.rake", "gem_tasks/flog.rake", "gem_tasks/gemspec.rake", "gem_tasks/rspec.rake", "gem_tasks/yard.rake", "lib/autotest/cucumber.rb", "lib/autotest/cucumber_mixin.rb", "lib/autotest/cucumber_rails.rb", "lib/autotest/cucumber_rails_rspec.rb", "lib/autotest/cucumber_rspec.rb", "lib/autotest/discover.rb", "lib/cucumber.rb", "lib/cucumber/ast.rb", "lib/cucumber/ast/background.rb", "lib/cucumber/ast/comment.rb", "lib/cucumber/ast/examples.rb", "lib/cucumber/ast/feature.rb", "lib/cucumber/ast/features.rb", "lib/cucumber/ast/filter.rb", "lib/cucumber/ast/outline_table.rb", "lib/cucumber/ast/py_string.rb", "lib/cucumber/ast/scenario.rb", "lib/cucumber/ast/scenario_outline.rb", "lib/cucumber/ast/step.rb", "lib/cucumber/ast/table.rb", "lib/cucumber/ast/tags.rb", "lib/cucumber/ast/visitor.rb", "lib/cucumber/broadcaster.rb", "lib/cucumber/cli/language_help_formatter.rb", "lib/cucumber/cli/main.rb", "lib/cucumber/core_ext/exception.rb", "lib/cucumber/core_ext/instance_exec.rb", "lib/cucumber/core_ext/proc.rb", "lib/cucumber/core_ext/string.rb", "lib/cucumber/formatter.rb", "lib/cucumber/formatter/ansicolor.rb", "lib/cucumber/formatter/console.rb", "lib/cucumber/formatter/pretty.rb", "lib/cucumber/formatter/profile.rb", "lib/cucumber/formatter/progress.rb", "lib/cucumber/formatter/rerun.rb", "lib/cucumber/formatter/unicode.rb", "lib/cucumber/formatters/unicode.rb", "lib/cucumber/jbehave.rb", "lib/cucumber/languages.yml", "lib/cucumber/parser.rb", "lib/cucumber/parser/basic.rb", "lib/cucumber/parser/feature.rb", "lib/cucumber/parser/feature.tt", "lib/cucumber/parser/i18n.tt", "lib/cucumber/parser/table.rb", "lib/cucumber/parser/table.tt", "lib/cucumber/parser/treetop_ext.rb", "lib/cucumber/platform.rb", "lib/cucumber/rails/rspec.rb", "lib/cucumber/rails/world.rb", "lib/cucumber/rake/task.rb", "lib/cucumber/step_definition.rb", "lib/cucumber/step_mother.rb", "lib/cucumber/version.rb", "rails_generators/cucumber/USAGE", "rails_generators/cucumber/cucumber_generator.rb", "rails_generators/cucumber/templates/cucumber", "rails_generators/cucumber/templates/cucumber.rake", "rails_generators/cucumber/templates/env.rb", "rails_generators/cucumber/templates/paths.rb", "rails_generators/cucumber/templates/webrat_steps.rb", "rails_generators/feature/USAGE", "rails_generators/feature/feature_generator.rb", "rails_generators/feature/templates/feature.erb", "rails_generators/feature/templates/steps.erb", "spec/cucumber/ast/background_spec.rb", "spec/cucumber/ast/feature_factory.rb", "spec/cucumber/ast/feature_spec.rb", "spec/cucumber/ast/py_string_spec.rb", "spec/cucumber/ast/scenario_outline_spec.rb", "spec/cucumber/ast/scenario_spec.rb", "spec/cucumber/ast/step_spec.rb", "spec/cucumber/ast/table_spec.rb", "spec/cucumber/broadcaster_spec.rb", "spec/cucumber/cli/main_spec.rb", "spec/cucumber/core_ext/proc_spec.rb", "spec/cucumber/core_ext/string_spec.rb", "spec/cucumber/formatter/ansicolor_spec.rb", "spec/cucumber/formatter/html/cucumber.css", "spec/cucumber/formatter/html/cucumber.js", "spec/cucumber/formatter/html/index.html", "spec/cucumber/formatter/html/jquery-1.3.min.js", "spec/cucumber/formatter/html/jquery.uitableedit.js", "spec/cucumber/formatters/profile_formatter_spec.rb", "spec/cucumber/parser/feature_parser_spec.rb", "spec/cucumber/parser/table_parser_spec.rb", "spec/cucumber/rails/stubs/mini_rails.rb", "spec/cucumber/rails/stubs/test_help.rb", "spec/cucumber/rails/world_spec.rb", "spec/cucumber/sell_cucumbers.feature", "spec/cucumber/step_definition_spec.rb", "spec/cucumber/step_mother_spec.rb", "spec/cucumber/treetop_parser/empty_feature.feature", "spec/cucumber/treetop_parser/empty_scenario.feature", "spec/cucumber/treetop_parser/empty_scenario_outline.feature", "spec/cucumber/treetop_parser/fit_scenario.feature", "spec/cucumber/treetop_parser/given_scenario.feature", "spec/cucumber/treetop_parser/invalid_scenario_outlines.feature", "spec/cucumber/treetop_parser/multiline_steps.feature", "spec/cucumber/treetop_parser/multiple_tables.feature", "spec/cucumber/treetop_parser/scenario_outline.feature", "spec/cucumber/treetop_parser/spaces.feature", "spec/cucumber/treetop_parser/test_dos.feature", "spec/cucumber/treetop_parser/with_comments.feature", "spec/cucumber/treetop_parser/with_tags.feature", "spec/cucumber/world/pending_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]\n+  s.files = ["History.txt", "License.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/cucumber", "config/hoe.rb", "config/requirements.rb", "cucumber.yml", "examples/cs/README.textile", "examples/cs/Rakefile", "examples/cs/compile.bat", "examples/cs/features/addition.feature", "examples/cs/features/step_definitons/calculator_steps.rb", "examples/cs/src/demo/Calculator.cs", "examples/dos_line_endings/Rakefile", "examples/dos_line_endings/features/dos_line_endings.feature", "examples/i18n/README.textile", "examples/i18n/Rakefile", "examples/i18n/ar/Rakefile", "examples/i18n/ar/features/addition.feature", "examples/i18n/ar/features/step_definitons/calculator_steps.rb", "examples/i18n/ar/lib/calculator.rb", "examples/i18n/da/Rakefile", "examples/i18n/da/features/step_definitons/kalkulator_steps.rb", "examples/i18n/da/features/summering.feature", "examples/i18n/da/lib/kalkulator.rb", "examples/i18n/de/Rakefile", "examples/i18n/de/features/addition.feature", "examples/i18n/de/features/division.feature", "examples/i18n/de/features/step_definitons/calculator_steps.rb", "examples/i18n/de/lib/calculator.rb", "examples/i18n/en/Rakefile", "examples/i18n/en/features/addition.feature", "examples/i18n/en/features/division.feature", "examples/i18n/en/features/step_definitons/calculator_steps.rb", "examples/i18n/en/lib/calculator.rb", "examples/i18n/es/Rakefile", "examples/i18n/es/features/adicion.feature", "examples/i18n/es/features/step_definitons/calculador_steps.rb", "examples/i18n/es/lib/calculador.rb", "examples/i18n/et/Rakefile", "examples/i18n/et/features/liitmine.feature", "examples/i18n/et/features/step_definitions/kalkulaator_steps.rb", "examples/i18n/et/lib/kalkulaator.rb", "examples/i18n/fi/Rakefile", "examples/i18n/fi/features/jakolasku.feature", "examples/i18n/fi/features/step_definitons/laskin_steps.rb", "examples/i18n/fi/features/yhteenlasku.feature", "examples/i18n/fi/lib/laskin.rb", "examples/i18n/fr/Rakefile", "examples/i18n/fr/features/addition.feature", "examples/i18n/fr/features/step_definitions/calculatrice_steps.rb", "examples/i18n/fr/lib/calculatrice.rb", "examples/i18n/id/Rakefile", "examples/i18n/id/features/addition.feature", "examples/i18n/id/features/division.feature", "examples/i18n/id/features/step_definitons/calculator_steps.rb", "examples/i18n/id/lib/calculator.rb", "examples/i18n/it/Rakefile", "examples/i18n/it/features/somma.feature", "examples/i18n/it/features/step_definitons/calcolatrice_steps.rb", "examples/i18n/it/lib/calcolatrice.rb", "examples/i18n/ja/README.txt", "examples/i18n/ja/Rakefile", "examples/i18n/ja/features/addition.feature", "examples/i18n/ja/features/division.feature", "examples/i18n/ja/features/step_definitons/calculator_steps.rb", "examples/i18n/ja/lib/calculator.rb", "examples/i18n/ko/Rakefile", "examples/i18n/ko/features/addition.feature", "examples/i18n/ko/features/division.feature", "examples/i18n/ko/features/step_definitons/calculator_steps.rb", "examples/i18n/ko/lib/calculator.rb", "examples/i18n/lt/Rakefile", "examples/i18n/lt/features/addition.feature", "examples/i18n/lt/features/division.feature", "examples/i18n/lt/features/step_definitons/calculator_steps.rb", "examples/i18n/lt/lib/calculator.rb", "examples/i18n/no/Rakefile", "examples/i18n/no/features/step_definitons/kalkulator_steps.rb", "examples/i18n/no/features/summering.feature", "examples/i18n/no/lib/kalkulator.rb", "examples/i18n/pt/Rakefile", "examples/i18n/pt/features/adicao.feature", "examples/i18n/pt/features/step_definitions/calculadora_steps.rb", "examples/i18n/pt/lib/calculadora.rb", "examples/i18n/ro/Rakefile", "examples/i18n/ro/features/step_definitons/calculator_steps.rb", "examples/i18n/ro/features/suma.feature", "examples/i18n/ro/lib/calculator.rb", "examples/i18n/se/Rakefile", "examples/i18n/se/features/step_definitons/kalkulator_steps.rb", "examples/i18n/se/features/summering.feature", "examples/i18n/se/lib/kalkulator.rb", "examples/i18n/zh-CN/Rakefile", "examples/i18n/zh-CN/features/addition.feature", "examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb", "examples/i18n/zh-CN/lib/calculator.rb", "examples/java/README.textile", "examples/java/Rakefile", "examples/java/features/hello.feature", "examples/java/features/step_definitons/hello_steps.rb", "examples/java/features/step_definitons/tree_steps.rb", "examples/java/features/tree.feature", "examples/java/src/cucumber/demo/Hello.java", "examples/jbehave/README.textile", "examples/jbehave/features/support/env.rb", "examples/jbehave/features/trading.feature", "examples/jbehave/pom.xml", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java", "examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java", "examples/selenium/Rakefile", "examples/selenium/features/search.feature", "examples/selenium/features/step_definitons/stories_steps.rb", "examples/self_test/README.textile", "examples/self_test/Rakefile", "examples/self_test/features/background/failing_background.feature", "examples/self_test/features/background/failing_background_after_success.feature", "examples/self_test/features/background/multiline_args_background.feature", "examples/self_test/features/background/passing_background.feature", "examples/self_test/features/background/pending_background.feature", "examples/self_test/features/background/scenario_outline_failing_background.feature", "examples/self_test/features/background/scenario_outline_passing_background.feature", "examples/self_test/features/call_undefined_step_from_step_def.feature", "examples/self_test/features/lots_of_undefined.feature", "examples/self_test/features/outline_sample.feature", "examples/self_test/features/sample.feature", "examples/self_test/features/step_definitions/sample_steps.rb", "examples/self_test/features/support/env.rb", "examples/test_unit/Rakefile", "examples/test_unit/features/step_definitions/test_unit_steps.rb", "examples/test_unit/features/test_unit.feature", "examples/tickets/Rakefile", "examples/tickets/cucumber.yml", "examples/tickets/features/172.feature", "examples/tickets/features/lib/eatting_machine.rb", "examples/tickets/features/lib/pantry.rb", "examples/tickets/features/scenario_outline.feature", "examples/tickets/features/step_definitons/scenario_outline_steps.rb", "examples/tickets/features/step_definitons/tickets_steps.rb", "examples/tickets/features/tickets.feature", "examples/watir/README.textile", "examples/watir/Rakefile", "examples/watir/features/search.feature", "examples/watir/features/step_definitons/search_steps.rb", "examples/watir/features/support/env.rb", "features/background.feature", "features/cucumber_cli.feature", "features/cucumber_cli_outlines.feature", "features/report_called_undefined_steps.feature", "features/step_definitions/cucumber_steps.rb", "features/step_definitions/extra_steps.rb", "features/support/env.rb", "gem_tasks/deployment.rake", "gem_tasks/environment.rake", "gem_tasks/features.rake", "gem_tasks/fix_cr_lf.rake", "gem_tasks/flog.rake", "gem_tasks/gemspec.rake", "gem_tasks/rspec.rake", "gem_tasks/yard.rake", "lib/autotest/cucumber.rb", "lib/autotest/cucumber_mixin.rb", "lib/autotest/cucumber_rails.rb", "lib/autotest/cucumber_rails_rspec.rb", "lib/autotest/cucumber_rspec.rb", "lib/autotest/discover.rb", "lib/cucumber.rb", "lib/cucumber/ast.rb", "lib/cucumber/ast/background.rb", "lib/cucumber/ast/comment.rb", "lib/cucumber/ast/examples.rb", "lib/cucumber/ast/feature.rb", "lib/cucumber/ast/features.rb", "lib/cucumber/ast/filter.rb", "lib/cucumber/ast/outline_table.rb", "lib/cucumber/ast/py_string.rb", "lib/cucumber/ast/scenario.rb", "lib/cucumber/ast/scenario_outline.rb", "lib/cucumber/ast/step.rb", "lib/cucumber/ast/table.rb", "lib/cucumber/ast/tags.rb", "lib/cucumber/ast/visitor.rb", "lib/cucumber/broadcaster.rb", "lib/cucumber/cli/language_help_formatter.rb", "lib/cucumber/cli/main.rb", "lib/cucumber/core_ext/exception.rb", "lib/cucumber/core_ext/instance_exec.rb", "lib/cucumber/core_ext/proc.rb", "lib/cucumber/core_ext/string.rb", "lib/cucumber/formatter.rb", "lib/cucumber/formatter/ansicolor.rb", "lib/cucumber/formatter/console.rb", "lib/cucumber/formatter/pretty.rb", "lib/cucumber/formatter/profile.rb", "lib/cucumber/formatter/progress.rb", "lib/cucumber/formatter/rerun.rb", "lib/cucumber/formatter/unicode.rb", "lib/cucumber/formatters/unicode.rb", "lib/cucumber/jbehave.rb", "lib/cucumber/languages.yml", "lib/cucumber/parser.rb", "lib/cucumber/parser/basic.rb", "lib/cucumber/parser/feature.rb", "lib/cucumber/parser/feature.tt", "lib/cucumber/parser/i18n.tt", "lib/cucumber/parser/table.rb", "lib/cucumber/parser/table.tt", "lib/cucumber/parser/treetop_ext.rb", "lib/cucumber/platform.rb", "lib/cucumber/rails/rspec.rb", "lib/cucumber/rails/world.rb", "lib/cucumber/rake/task.rb", "lib/cucumber/step_definition.rb", "lib/cucumber/step_mother.rb", "lib/cucumber/version.rb", "rails_generators/cucumber/USAGE", "rails_generators/cucumber/cucumber_generator.rb", "rails_generators/cucumber/templates/cucumber", "rails_generators/cucumber/templates/cucumber.rake", "rails_generators/cucumber/templates/env.rb", "rails_generators/cucumber/templates/paths.rb", "rails_generators/cucumber/templates/webrat_steps.rb", "rails_generators/feature/USAGE", "rails_generators/feature/feature_generator.rb", "rails_generators/feature/templates/feature.erb", "rails_generators/feature/templates/steps.erb", "spec/cucumber/ast/background_spec.rb", "spec/cucumber/ast/feature_factory.rb", "spec/cucumber/ast/feature_spec.rb", "spec/cucumber/ast/py_string_spec.rb", "spec/cucumber/ast/scenario_outline_spec.rb", "spec/cucumber/ast/scenario_spec.rb", "spec/cucumber/ast/step_spec.rb", "spec/cucumber/ast/table_spec.rb", "spec/cucumber/broadcaster_spec.rb", "spec/cucumber/cli/main_spec.rb", "spec/cucumber/core_ext/proc_spec.rb", "spec/cucumber/core_ext/string_spec.rb", "spec/cucumber/formatter/ansicolor_spec.rb", "spec/cucumber/formatter/html/cucumber.css", "spec/cucumber/formatter/html/cucumber.js", "spec/cucumber/formatter/html/index.html", "spec/cucumber/formatter/html/jquery-1.3.min.js", "spec/cucumber/formatter/html/jquery.uitableedit.js", "spec/cucumber/formatters/profile_formatter_spec.rb", "spec/cucumber/parser/feature_parser_spec.rb", "spec/cucumber/parser/table_parser_spec.rb", "spec/cucumber/rails/stubs/mini_rails.rb", "spec/cucumber/rails/stubs/test_help.rb", "spec/cucumber/rails/world_spec.rb", "spec/cucumber/sell_cucumbers.feature", "spec/cucumber/step_definition_spec.rb", "spec/cucumber/step_mother_spec.rb", "spec/cucumber/treetop_parser/empty_feature.feature", "spec/cucumber/treetop_parser/empty_scenario.feature", "spec/cucumber/treetop_parser/empty_scenario_outline.feature", "spec/cucumber/treetop_parser/fit_scenario.feature", "spec/cucumber/treetop_parser/given_scenario.feature", "spec/cucumber/treetop_parser/invalid_scenario_outlines.feature", "spec/cucumber/treetop_parser/multiline_steps.feature", "spec/cucumber/treetop_parser/multiple_tables.feature", "spec/cucumber/treetop_parser/scenario_outline.feature", "spec/cucumber/treetop_parser/spaces.feature", "spec/cucumber/treetop_parser/test_dos.feature", "spec/cucumber/treetop_parser/with_comments.feature", "spec/cucumber/treetop_parser/with_tags.feature", "spec/cucumber/world/pending_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]\n   s.has_rdoc = true\n   s.homepage = %q{http://github.com/aslakhellesoy/cucumber}\n   s.rdoc_options = ["--main", "README.txt"]\ndiff --git a/features/cucumber_cli_outlines.feature b/features/cucumber_cli_outlines.feature\nindex 446d316b..b55042d7 100644\n--- a/features/cucumber_cli_outlines.feature\n+++ b/features/cucumber_cli_outlines.feature\n@@ -43,8 +43,8 @@ Feature: Cucumber command line\n       Feature: Outline Sample\n \n         Scenario Outline: Test state          # features/outline_sample.feature:5\n-          Given <state> without a table\n-          Given <other_state> without a table\n+          Given <state> without a table       # features/step_definitions/sample_steps.rb:12\n+          Given <other_state> without a table # features/step_definitions/sample_steps.rb:12\n \n         Examples: Rainbow colours\n           | state   | other_state |\ndiff --git a/gem_tasks/gemspec.rake b/gem_tasks/gemspec.rake\nindex 88a6a72f..85d62d20 100644\n--- a/gem_tasks/gemspec.rake\n+++ b/gem_tasks/gemspec.rake\n@@ -4,7 +4,7 @@ namespace :gemspec do\n     File.open(\'cucumber.gemspec\', \'w\') {|io| io.write($hoe.spec.to_ruby)}\n     puts "1) git commit -a -m \\"Release #{Cucumber::VERSION::STRING}\\""\n     puts "2) git tag -a \\"v#{Cucumber::VERSION::STRING}\\" -m \\"Release #{Cucumber::VERSION::STRING}\\""\n-    puts "3) git push --tags"\n-    puts "4) Bounce the version in version.rb"\n+    puts "3) git push"\n+    puts "4) git push --tags"\n   end\n end\n\\ No newline at end of file\ndiff --git a/lib/cucumber/ast/examples.rb b/lib/cucumber/ast/examples.rb\nindex 1fddf27a..4e899312 100644\n--- a/lib/cucumber/ast/examples.rb\n+++ b/lib/cucumber/ast/examples.rb\n@@ -10,6 +10,10 @@ module Cucumber\n         @outline_table.accept(visitor, nil)\n       end\n \n+      def each_example_row(&proc)\n+        @outline_table.each_cells_row(&proc)\n+      end\n+\n       def at_lines?(lines)\n         lines.empty? || lines.index(@line) || @outline_table.at_lines?(lines)\n       end\ndiff --git a/lib/cucumber/ast/scenario_outline.rb b/lib/cucumber/ast/scenario_outline.rb\nindex 2ecb92a7..73917310 100644\n--- a/lib/cucumber/ast/scenario_outline.rb\n+++ b/lib/cucumber/ast/scenario_outline.rb\n@@ -39,6 +39,12 @@ module Cucumber\n         end\n       end\n \n+      def each_example_row(&proc)\n+        @examples_array.each do |examples|\n+          examples.each_example_row(&proc)\n+        end\n+      end\n+\n       def execute_row(cells, visitor, &proc)\n         exception = nil\n         \ndiff --git a/lib/cucumber/ast/step.rb b/lib/cucumber/ast/step.rb\nindex 3b40249b..224122ea 100644\n--- a/lib/cucumber/ast/step.rb\n+++ b/lib/cucumber/ast/step.rb\n@@ -26,13 +26,31 @@ module Cucumber\n \n       def accept(visitor)\n         execute(visitor)\n-        visitor.visit_step_name(@keyword, @name, @status, @step_definition, source_indent)\n+\n+        if @status == :outline\n+          step_definition = find_first_name_and_step_definition_from_examples(visitor)\n+        else\n+          step_definition = @step_definition\n+        end\n+        visitor.visit_step_name(@keyword, @name, @status, step_definition, source_indent)\n         @multiline_args.each do |multiline_arg|\n           visitor.visit_multiline_arg(multiline_arg, @status)\n         end\n         @exception\n       end\n \n+      def find_first_name_and_step_definition_from_examples(visitor)\n+        # @scenario is always a ScenarioOutline in this case\n+        @scenario.each_example_row do |cells|\n+          argument_hash       = cells.to_hash\n+          delimited_arguments = delimit_argument_names(argument_hash)\n+          name                = replace_name_arguments(delimited_arguments)\n+          step_definition     = visitor.step_definition(name) rescue nil\n+          return step_definition if step_definition\n+        end\n+        nil\n+      end\n+\n       def to_sexp\n         [:step, @line, @keyword, @name, *@multiline_args.map{|arg| arg.to_sexp}]\n       end\ndiff --git a/lib/cucumber/ast/table.rb b/lib/cucumber/ast/table.rb\nindex 268ad61d..10cba420 100644\n--- a/lib/cucumber/ast/table.rb\n+++ b/lib/cucumber/ast/table.rb\n@@ -66,6 +66,10 @@ module Cucumber\n         @raw[1..-1]\n       end\n \n+      def each_cells_row(&proc)\n+        cells_rows.each(&proc)\n+      end\n+\n       # For testing only\n       def to_sexp #:nodoc:\n         [:table, *cells_rows.map{|row| row.to_sexp}]\ndiff --git a/lib/cucumber/formatter/console.rb b/lib/cucumber/formatter/console.rb\nindex d4e44027..cadbbaf6 100644\n--- a/lib/cucumber/formatter/console.rb\n+++ b/lib/cucumber/formatter/console.rb\n@@ -7,17 +7,20 @@ module Cucumber\n       FORMATS = Hash.new{|hash, format| hash[format] = method(format).to_proc}\n \n       def format_step(keyword, step_name, status, step_definition, source_indent)\n-        line = if step_definition # nil for :outline\n-          comment = if source_indent\n-            c = (\' # \' + step_definition.file_colon_line).indent(source_indent)\n-            format_string(c, :comment)\n-          else\n-            \'\'\n-          end\n-          keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment\n+        comment = if source_indent\n+          c = (\' # \' + step_definition.file_colon_line).indent(source_indent)\n+          format_string(c, :comment)\n         else\n-          keyword + " " + step_name\n+          \'\'\n         end\n+\n+        begin\n+          line = keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment\n+        rescue\n+          # It didn\'t match. This often happens for :outline steps\n+          line = keyword + " " + step_name + comment\n+        end\n+\n         format_string(line, status)\n       end\n \ndiff --git a/lib/cucumber/version.rb b/lib/cucumber/version.rb\nindex 6cbf251a..24c0af9f 100644\n--- a/lib/cucumber/version.rb\n+++ b/lib/cucumber/version.rb\n@@ -3,7 +3,7 @@ module Cucumber #:nodoc:\n     MAJOR = 0\n     MINOR = 1\n     TINY  = 99\n-    PATCH = 13 # Set to nil for official release\n+    PATCH = 14 # Set to nil for official release\n \n     STRING = [MAJOR, MINOR, TINY, PATCH].compact.join(\'.\')\n   end\n', 'commit_subject': 'Implement location comment for outline steps. Release 0.1.99.14.', 'repo_name': 'cucumber/cucumber-ruby', 'committer': {'name': 'Aslak Hellesøy', 'email': '9ef4f83a0ea93e22b183f4bda513ab25aeda16aa@gmail.com', 'time_sec': '1233167716', 'tz_offset': '60', 'date': {'seconds': '1233167716'}}, 'commit_tree': '4f3eadc22b00c110e1526f4746d82838ee22d8ed', 'commit_message': 'Implement location comment for outline steps. Release 0.1.99.14.\n', 'language_name': 'JavaScript', 'license': 'mit', 'hunks': '@@ -7,17 +7,20 @@ module Cucumber\n       FORMATS = Hash.new{|hash, format| hash[format] = method(format).to_proc}\n \n       def format_step(keyword, step_name, status, step_definition, source_indent)\n-        line = if step_definition # nil for :outline\n-          comment = if source_indent\n-            c = (\' # \' + step_definition.file_colon_line).indent(source_indent)\n-            format_string(c, :comment)\n-          else\n-            \'\'\n-          end\n-          keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment\n+        comment = if source_indent\n+          c = (\' # \' + step_definition.file_colon_line).indent(source_indent)\n+          format_string(c, :comment)\n         else\n-          keyword + " " + step_name\n+          \'\'\n         end\n+\n+        begin\n+          line = keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment\n+        rescue\n+          # It didn\'t match. This often happens for :outline steps\n+          line = keyword + " " + step_name + comment\n+        end\n+\n         format_string(line, status)\n       end\n \n', 'addition_count': 12, 'deletion_count': 9, 'src_file': 'a/lib/cucumber/formatter/console.rb', 'tgt_file': 'b/lib/cucumber/formatter/console.rb', 'file_extension': '.rb', 'before_file': '# frozen_string_literal: true\n\n# rubocop:disable Metrics/ModuleLength\n\nrequire \'cucumber/formatter/ansicolor\'\nrequire \'cucumber/formatter/duration\'\n      FORMATS = Hash.new{|hash, format| hash[format] = method(format).to_proc}\n\n      def format_step(keyword, step_name, status, step_definition, source_indent)\n        line = if step_definition # nil for :outline\n          comment = if source_indent\n            c = (\' # \' + step_definition.file_colon_line).indent(source_indent)\n            format_string(c, :comment)\n          else\n            \'\'\n          end\n          keyword + " " + step_definition.format_args(step_name, format_for(status, :param)) + comment\n        else\n          keyword + " " + step_name\n        end\n        format_string(line, status)\n      end\n\n    #\n    # During output, each line is processed by passing it to the formatter Proc\n    # which returns the formatted (e.g. colored) string.\n\n    module Console\n      extend ANSIColor\n      include Duration\n\n      def format_step(keyword, step_match, status, source_indent)\n        comment = if source_indent\n                    c = indent("# #{step_match.location}", source_indent)\n                    format_string(c, :comment)\n                  else\n                    \'\'\n                  end\n\n        format = format_for(status, :param)\n        line = keyword + step_match.format_args(format) + comment\n        format_string(line, status)\n      end\n\n      def format_string(o, status)\n        fmt = format_for(status)\n        o.to_s.split("\\n").map do |line|\n          if Proc == fmt.class\n            fmt.call(line)\n          else\n            fmt % line\n          end\n        end.join("\\n")\n      end\n\n      def print_elements(elements, status, kind)\n        return if elements.empty?\n\n        element_messages = element_messages(elements, status)\n        print_element_messages(element_messages, status, kind)\n      end\n\n      def print_element_messages(element_messages, status, kind)\n        if element_messages.any?\n          @io.puts(format_string("(::) #{status} #{kind} (::)", status))\n          @io.puts\n          @io.flush\n        end\n\n        element_messages.each do |message|\n          @io.puts(format_string(message, status))\n          @io.puts\n          @io.flush\n        end\n      end\n\n      def print_statistics(duration, config, counts, issues)\n        if issues.any?\n          @io.puts issues.to_s\n          @io.puts\n        end\n\n        @io.puts counts.to_s\n        @io.puts(format_duration(duration)) if duration && config.duration?\n\n        if config.randomize?\n          @io.puts\n          @io.puts "Randomized with seed #{config.seed}"\n        end\n\n        @io.flush\n      end\n\n      def print_exception(e, status, indent)\n        string = exception_message_string(e, indent)\n        @io.puts(format_string(string, status))\n      end\n\n      def exception_message_string(e, indent_amount)\n        message = "#{e.message} (#{e.class})".dup.force_encoding(\'UTF-8\')\n        message = linebreaks(message, ENV[\'CUCUMBER_TRUNCATE_OUTPUT\'].to_i)\n\n        indent("#{message}\\n#{e.backtrace.join("\\n")}", indent_amount)\n      end\n\n      # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/10655\n      def linebreaks(msg, max)\n        return msg unless max && max > 0\n\n        msg.gsub(/.{1,#{max}}(?:\\s|\\Z)/) do\n          (Regexp.last_match(0) + 5.chr).gsub(/\\n\\005/, "\\n").gsub(/\\005/, "\\n")\n        end.rstrip\n      end\n\n      def collect_snippet_data(test_step, ast_lookup)\n        # collect snippet data for undefined steps\n        keyword = ast_lookup.snippet_step_keyword(test_step)\n        @snippets_input << Console::SnippetData.new(keyword, test_step)\n      end\n\n      def collect_undefined_parameter_type_names(undefined_parameter_type)\n        @undefined_parameter_types << undefined_parameter_type.type_name\n      end\n\n      def print_snippets(options)\n        return unless options[:snippets]\n\n        snippet_text_proc = lambda do |step_keyword, step_name, multiline_arg|\n          snippet_text(step_keyword, step_name, multiline_arg)\n        end\n        do_print_snippets(snippet_text_proc) unless @snippets_input.empty?\n\n        @undefined_parameter_types.map do |type_name|\n          do_print_undefined_parameter_type_snippet(type_name)\n        end\n      end\n\n      def do_print_snippets(snippet_text_proc)\n        snippets = @snippets_input.map do |data|\n          snippet_text_proc.call(data.actual_keyword, data.step.text, data.step.multiline_arg)\n        end.uniq\n\n        text = "\\nYou can implement step definitions for undefined steps with these snippets:\\n\\n"\n        text += snippets.join("\\n\\n")\n        @io.puts format_string(text, :undefined)\n\n        @io.puts\n        @io.flush\n      end\n\n      def print_passing_wip(config, passed_test_cases, ast_lookup)\n        return unless config.wip?\n\n        messages = passed_test_cases.map do |test_case|\n          scenario_source = ast_lookup.scenario_source(test_case)\n          keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword\n          linebreaks("#{test_case.location.on_line(test_case.location.lines.max)}:in `#{keyword}: #{test_case.name}\'", ENV[\'CUCUMBER_TRUNCATE_OUTPUT\'].to_i)\n        end\n        do_print_passing_wip(messages)\n      end\n\n      def do_print_passing_wip(passed_messages)\n        if passed_messages.any?\n          @io.puts format_string("\\nThe --wip switch was used, so I didn\'t expect anything to pass. These scenarios passed:", :failed)\n          print_element_messages(passed_messages, :passed, \'scenarios\')\n        else\n          @io.puts format_string("\\nThe --wip switch was used, so the failures were expected. All is good.\\n", :passed)\n        end\n      end\n\n      def attach(src, media_type)\n        return unless media_type == \'text/x.cucumber.log+plain\'\n        return unless @io\n\n        @io.puts\n        @io.puts(format_string(src, :tag))\n        @io.flush\n      end\n\n      def print_profile_information\n        return if @options[:skip_profile_information] || @options[:profiles].nil? || @options[:profiles].empty?\n\n        do_print_profile_information(@options[:profiles])\n      end\n\n      def do_print_profile_information(profiles)\n        profiles_sentence = if profiles.size == 1\n                              profiles.first\n                            else\n                              "#{profiles[0...-1].join(\', \')} and #{profiles.last}"\n                            end\n\n        @io.puts "Using the #{profiles_sentence} profile#{\'s\' if profiles.size > 1}..."\n      end\n\n      def do_print_undefined_parameter_type_snippet(type_name)\n        camelized = type_name.split(/_|-/).collect(&:capitalize).join\n\n        @io.puts [\n          "The parameter #{type_name} is not defined. You can define a new one with:",\n          \'\',\n          \'ParameterType(\',\n          "  name:        \'#{type_name}\',",\n          \'  regexp:      /some regexp here/,\',\n          "  type:        #{camelized},",\n          \'  # The transformer takes as many arguments as there are capture groups in the regexp,\',\n          \'  # or just one if there are none.\',\n          "  transformer: ->(s) { #{camelized}.new(s) }",\n          \')\',\n          \'\'\n        ].join("\\n")\n      end\n\n      def indent(string, padding)\n        if padding >= 0\n          string.gsub(/^/, \' \' * padding)\n        else\n          string.gsub(/^ {0,#{-padding}}/, \'\')\n        end\n      end\n\n      private\n\n      FORMATS = Hash.new { |hash, format| hash[format] = method(format).to_proc }\n\n      def format_for(*keys)\n        key = keys.join(\'_\').to_sym\n        fmt = FORMATS[key]\n        raise "No format for #{key.inspect}: #{FORMATS.inspect}" if fmt.nil?\n\n        fmt\n      end\n\n      def element_messages(elements, status)\n        elements.map do |element|\n          if status == :failed\n            exception_message_string(element.exception, 0)\n          else\n            linebreaks(element.backtrace_line, ENV[\'CUCUMBER_TRUNCATE_OUTPUT\'].to_i)\n          end\n        end\n      end\n\n      def snippet_text(step_keyword, step_name, multiline_arg)\n        keyword = Cucumber::Gherkin::I18n.code_keyword_for(step_keyword).strip\n        config.snippet_generators.map do |generator|\n          generator.call(keyword, step_name, multiline_arg, config.snippet_type)\n        end.join("\\n")\n      end\n\n      class SnippetData\n        attr_reader :actual_keyword, :step\n\n        def initialize(actual_keyword, step)\n          @actual_keyword = actual_keyword\n          @step = step\n        end\n      end\n    end\n  end\nend\n# rubocop:enable Metrics/ModuleLength\n', 'message': 'Implement location comment for outline steps. Release 0.1.99.14.\n', 'author_name': 'Aslak Hellesøy', 'lang': 'rb'}