class Danger::DangerCodeCoverage

Generate code coverage reports on pull requests based on jenkins code-coverage-api-plugin.

@example Generate report for each changed file.

code_coverage.report

@example Use auth token.

code_coverage.report(
  auth_user: 'user',
  auth_token: 'token'

)

@see Kyaak/danger-code_coverage @tags danger, jenkins, coverage, code-coverage, analysis

Constants

EMPTY_COLUMN
TABLE_HEADER_CONDITIONAL
TABLE_HEADER_FILE
TABLE_HEADER_INSTRUCTION
TABLE_HEADER_LINE
TABLE_HEADER_METHOD
TABLE_HEADER_TOTAL
TABLE_TITLE

Public Class Methods

new(dangerfile) click to toggle source

Initialize code_coverage plugin.

Calls superclass method
# File lib/code_coverage/plugin.rb, line 33
def initialize(dangerfile)
  @target_files = nil
  @auth = nil
  @table = CodeCoverage::MarkdownTable.new
  @table.header(TABLE_HEADER_FILE,
                TABLE_HEADER_TOTAL,
                TABLE_HEADER_METHOD,
                TABLE_HEADER_LINE,
                TABLE_HEADER_CONDITIONAL,
                TABLE_HEADER_INSTRUCTION)
  super(dangerfile)
end

Public Instance Methods

report(*args) click to toggle source

Create an overview report.

@param args Configuration settings @return [void]

# File lib/code_coverage/plugin.rb, line 50
def report(*args)
  options = args.first
  sort_order = options && options[:sort]
  if sort_order && !sort_order.eql?(:ascending) && !sort_order.eql?(:descending)
    raise(ArgumentError.new('Invalid configuration, use [:ascending, :descending]'))
  end

  check_auth(options)

  items = coverage_items
  items.select! { |item| file_in_changeset?(item.file) }
  items.each(&method(:update_item))
  items.sort_by! do |item|
    if sort_order.eql?(:ascending)
      item.total
    else
      -item.total
    end
  end
  items.each(&method(:add_entry))

  return if @table.size.zero?

  markdown("#{TABLE_TITLE}\n\n#{@table.to_markdown}")
end

Private Instance Methods

add_entry(item) click to toggle source
# File lib/code_coverage/plugin.rb, line 86
def add_entry(item)
  @table.line(item.file,
              item.total,
              item.method,
              item.line,
              item.conditional,
              item.instruction)
end
auth_token(options) click to toggle source
# File lib/code_coverage/plugin.rb, line 136
def auth_token(options)
  options && !options[:auth_token].nil? ? options[:auth_token] : nil
end
auth_user(options) click to toggle source
# File lib/code_coverage/plugin.rb, line 132
def auth_user(options)
  options && !options[:auth_user].nil? ? options[:auth_user] : nil
end
check_auth(options) click to toggle source
# File lib/code_coverage/plugin.rb, line 140
def check_auth(options)
  user = auth_user(options)
  token = auth_token(options)
  return unless user && token

  @auth = {
    user: user,
    token: token
  }
end
convert_entry(value) click to toggle source
# File lib/code_coverage/plugin.rb, line 95
def convert_entry(value)
  return EMPTY_COLUMN unless value

  value
end
coverage_items() click to toggle source
# File lib/code_coverage/plugin.rb, line 160
def coverage_items
  content = coverage_json
  CodeCoverage::CoverageParser.new.parse(content)
end
coverage_json() click to toggle source
# File lib/code_coverage/plugin.rb, line 165
def coverage_json
  options = { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE }
  options[:http_basic_authentication] = [@auth[:user], @auth[:token]] if @auth
  OpenURI.open_uri("#{ENV['BUILD_URL']}/coverage/result/api/json?depth=5", options).read
end
file_in_changeset?(file) click to toggle source
# File lib/code_coverage/plugin.rb, line 151
def file_in_changeset?(file)
  result = target_files.select { |value| value =~ %r{.*#{file}} }
  !result.empty?
end
target_files() click to toggle source
# File lib/code_coverage/plugin.rb, line 156
def target_files
  @target_files ||= git.modified_files + git.added_files
end
total(item) click to toggle source
# File lib/code_coverage/plugin.rb, line 101
def total(item)
  count = 0
  sum = 0

  unless convert_entry(item.method).eql?(EMPTY_COLUMN)
    count += 1
    sum += convert_entry(item.method)
  end

  unless convert_entry(item.line).eql?(EMPTY_COLUMN)
    count += 1
    sum += convert_entry(item.line)
  end

  unless convert_entry(item.conditional).eql?(EMPTY_COLUMN)
    count += 1
    sum += convert_entry(item.conditional)
  end

  unless convert_entry(item.instruction).eql?(EMPTY_COLUMN)
    count += 1
    sum += convert_entry(item.instruction)
  end

  if count.zero?
    0.0
  else
    (sum / count).round(2)
  end
end
update_item(item) click to toggle source
# File lib/code_coverage/plugin.rb, line 78
def update_item(item)
  item.method = convert_entry(item.method)
  item.line = convert_entry(item.line)
  item.conditional = convert_entry(item.conditional)
  item.instruction = convert_entry(item.instruction)
  item.total = total(item)
end