<commit_before>require 'cucumber/formatter/ordered_xml_markup'

module Cucumber
  module Formatter
    class Junit < Cucumber::Ast::Visitor

      def initialize(step_mother, io, options)
        super(step_mother)
        raise "You *must* specify --out DIR for the junit formatter" unless String === io && File.directory?(io)
        @reportdir = io
        @options = options
      end

      def visit_feature(feature)
        @failures = @errors = @tests = 0
        @builder = OrderedXmlMarkup.new( :indent => 2 )
        @time = 0
        super

        @testsuite = OrderedXmlMarkup.new( :indent => 2 )
        @testsuite.instruct!
        @testsuite.testsuite(
          :failures => @failures,
          :errors => @errors,
          :tests => @tests,
          :time => "%.6f" % @time,
        :name => @feature_name ) do
          @testsuite << @builder.target!
        end

        basename = File.basename(feature.file)[0...-File.extname(feature.file).length]
        feature_filename = File.join(@reportdir, "TEST-#{basename}.xml")
        File.open(feature_filename, 'w') { |file| file.write(@testsuite.target!) }
      end

      def visit_background(name)
        @in_background = true
        super
        @in_background = false
      end

      def visit_feature_name(name)
        lines = name.split(/\r?\n/)
        @feature_name = lines[0].sub(/Feature\:/, '').strip
      end

      def visit_scenario_name(keyword, name, file_colon_line, source_indent)
        scenario_name = name.strip
        scenario_name = "Unnamed scenario" if name == ""
        @scenario = scenario_name
        @outline = keyword.include?('Scenario Outline')
        @output = "Scenario#{ " outline" if @outline}: #{@scenario}\n\n"
      end

      def visit_steps(steps)
        return if @in_background
        start = Time.now
        super
        duration = Time.now - start
        unless @outline
          if steps.failed?
            steps.each { |step| @output += "#{step.keyword} #{step.name}\n" }
            @output += "\nMessage:\n"
          end
          build_testcase(duration, steps.status, steps.exception)
        end
      end

      def visit_outline_table(outline_table)
        @header_row = true
        super(outline_table)
      end

      def visit_table_row(table_row)
        if @outline
          start = Time.now
          super(table_row)
          duration = Time.now - start
          unless @header_row
            name_suffix = " (outline example : #{table_row.name})"
            if table_row.failed?
              @output += "Example row: #{table_row.name}\n"
              @output += "\nMessage:\n"
            end
            build_testcase(duration, table_row.status, table_row.exception,  name_suffix)
          end
        else
          super(table_row)
        end
        @header_row = false
      end

      private

        def build_testcase(duration, status, exception = nil, suffix = "")
          @time += duration
          classname = "#{@feature_name}.#{@scenario}"
          name = "#{@scenario}#{suffix}"
          @builder.testcase(:classname => classname, :name => name, :time => "%.6f" % duration) do
            if status != :passed
              @builder.failure(:message => "#{status.to_s} #{name}", :type => status.to_s) do
                @builder.text! @output
                @builder.text!(format_exception(exception)) if exception
              end
              @failures += 1
            end
          end
          @tests += 1
        end

        def format_exception(exception)
          (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
        end
    end
  end
end
<commit_msg>skip creation of testcase xml unless status is either passed or failed (there is currently no way to my knowledge to express skipped /ignored tests in the old junitreport xml format<commit_after>require 'cucumber/formatter/ordered_xml_markup'

module Cucumber
  module Formatter
    class Junit < Cucumber::Ast::Visitor

      def initialize(step_mother, io, options)
        super(step_mother)
        raise "You *must* specify --out DIR for the junit formatter" unless String === io && File.directory?(io)
        @reportdir = io
        @options = options
      end

      def visit_feature(feature)
        @failures = @errors = @tests = 0
        @builder = OrderedXmlMarkup.new( :indent => 2 )
        @time = 0
        super

        @testsuite = OrderedXmlMarkup.new( :indent => 2 )
        @testsuite.instruct!
        @testsuite.testsuite(
          :failures => @failures,
          :errors => @errors,
          :tests => @tests,
          :time => "%.6f" % @time,
        :name => @feature_name ) do
          @testsuite << @builder.target!
        end

        basename = File.basename(feature.file)[0...-File.extname(feature.file).length]
        feature_filename = File.join(@reportdir, "TEST-#{basename}.xml")
        File.open(feature_filename, 'w') { |file| file.write(@testsuite.target!) }
      end

      def visit_background(name)
        @in_background = true
        super
        @in_background = false
      end

      def visit_feature_name(name)
        lines = name.split(/\r?\n/)
        @feature_name = lines[0].sub(/Feature\:/, '').strip
      end

      def visit_scenario_name(keyword, name, file_colon_line, source_indent)
        scenario_name = name.strip
        scenario_name = "Unnamed scenario" if name == ""
        @scenario = scenario_name
        @outline = keyword.include?('Scenario Outline')
        @output = "Scenario#{ " outline" if @outline}: #{@scenario}\n\n"
      end

      def visit_steps(steps)
        return if @in_background
        start = Time.now
        super
        duration = Time.now - start
        unless @outline
          if steps.failed?
            steps.each { |step| @output += "#{step.keyword} #{step.name}\n" }
            @output += "\nMessage:\n"
          end
          build_testcase(duration, steps.status, steps.exception)
        end
      end

      def visit_outline_table(outline_table)
        @header_row = true
        super(outline_table)
      end

      def visit_table_row(table_row)
        if @outline
          start = Time.now
          super(table_row)
          duration = Time.now - start
          unless @header_row
            name_suffix = " (outline example : #{table_row.name})"
            if table_row.failed?
              @output += "Example row: #{table_row.name}\n"
              @output += "\nMessage:\n"
            end
            build_testcase(duration, table_row.status, table_row.exception,  name_suffix)
          end
        else
          super(table_row)
        end
        @header_row = false
      end

      private

        def build_testcase(duration, status, exception = nil, suffix = "")
          @time += duration
          classname = "#{@feature_name}.#{@scenario}"
          name = "#{@scenario}#{suffix}"
          if status == :passed || status == :failed
            @builder.testcase(:classname => classname, :name => name, :time => "%.6f" % duration) do
              if status == :failed
                @builder.failure(:message => "#{status.to_s} #{name}", :type => status.to_s) do
                  @builder.text! @output
                  @builder.text!(format_exception(exception)) if exception
                end
                @failures += 1
              end
            end
            @tests += 1
          end
        end

        def format_exception(exception)
          (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
        end
    end
  end
end

{'fraction_non_alphanumeric': 0.11844863731656184, 'fraction_numerical': 0.002620545073375262, 'mean_word_length': 1.934640522875817, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6695681', 'n_tokens_mistral': 2232, 'n_tokens_neox': 2189, 'n_words': 514}