class GitTest

Constants

LHS
RHS

Public Instance Methods

join() click to toggle source
# File lib/git_test.rb, line 63
def join
  begin
    mapping = CSV.read(options[:mapping], headers: true, skip_lines: /#/)
    mapping.each do |row|
      row["pattern"] = Regexp.new(row["pattern"], Regexp::IGNORECASE)
    end
  rescue CSV::MalformedCSVError, ArgumentError => e
    $stderr.puts "An error occured when parsing the mapping file '#{options[:mapping]}:\n #{e}"
    exit 1
  end

  begin
    change_rec = CSV.read(options[:change_recommendation], headers: true)
  rescue CSV::MalformedCSVError, ArgumentError => e
    $stderr.puts "An error occured when parsing the change recommendation '#{options[:change_recommendation]}:\n #{e}"
    exit 1
  end

  pattern_matched = Hash.new

  # print header
  CSV {|r| r << %W(#{LHS} #{RHS} support #{LHS}_tested_by #{RHS}_tested_by)}
  change_rec.each do |row|
    support = row["support"].to_r.to_f

    tests = {'lhs': Set.new, 'rhs': Set.new}

    ['lhs','rhs'].each do |side|
      file = row[side]
      # check if the files has already been mapped
      if pattern_matched[file].nil?
        pattern_matched[file] = []
        # iterate through mapping file to find matching tests
        mapping.each do |mapping_row|
          pattern = mapping_row["pattern"]
          test = mapping_row["test"]
          if file =~ pattern
            pattern_matched[file] << test
          end
        end
      end
      tests[side] = pattern_matched[file]
    end

    # print new row
    CSV {|r| r << [row['lhs'], row['rhs'], support, (tests['lhs'].empty? ? nil : tests['lhs'].join(",")), (tests['rhs'].empty? ? nil : tests['rhs'].join(","))]}
  end                          
end
plan() click to toggle source
# File lib/git_test.rb, line 10
def plan
  begin
    change_rec = CSV.read(options[:change_recommendation], headers: true)
  rescue CSV::MalformedCSVError, ArgumentError => e
    $stderr.puts "An error occured when parsing the change recommendation '#{options[:change_recommendation]}':\n #{e}"
    exit 1
  end


  test_plan = Hash.new
  coverage = {LHS => Set.new, RHS => Set.new}

  change_rec.each do |row|
    support = row["support"].to_r.to_f
    # find relevant tests
    [LHS,RHS].each do |side|
      tests = (row["#{side}_tested_by"].nil? ? [] : row["#{side}_tested_by"].split(","))
      file = row[side]
      tests.each do |test|
        coverage[side] << file
        if test_plan[test].nil?
          test_plan[test] = {'cg' => 0, LHS => Set.new, RHS => Set.new}
        end
        test_plan[test]['cg'] += support
        test_plan[test][side] << file 
      end
    end
  end
  # normalize the cumulative gain
  max_cg = test_plan.map {|_,v| v['cg']}.max
  test_plan.each {|test,v| test_plan[test]['cg'] = v['cg']/max_cg}

  # print items with missing test mapping to stderr
  uncovered = Hash.new
  [LHS,RHS].each do |side|
    items_in_plan = change_rec.map {|row| row[side]}.to_set
    if coverage[side].size < items_in_plan.size
      uncovered[side+'_without_test_mapping'] = items_in_plan - coverage[side]
    end
  end
  if !uncovered.empty?
    $stderr.puts uncovered.to_json
  end
  # print testplan to stdout
  $stdout.puts "test,impact,#{LHS}_covered,#{RHS}_covered"
  test_plan.sort_by {|k,v| [v[LHS].size,v[RHS].size].max}.each do |test,v|
    $stdout.puts "#{test},#{v['cg']},#{v[LHS].size},#{v[RHS].size}"
  end
end