Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SimpleCov html coverage file parser
require "nokogiri"
class CoverageParser
attr_reader :files,
:files_count,
:coverage_percent,
:avg_hit,
:lines_total,
:lines_relevant,
:lines_missed,
:lines_covered
def initialize(data)
doc = Nokogiri::HTML(data)
@files = doc.css("#AllFiles table.file_list tbody tr").map do |el|
parse_element(el)
end
@files_count = files.size
@files.sort! { |a,b| a[:coverage_percent] <=> b[:coverage_percent] }
if @files.any?
# Calculate average hit
sum = files.map { |f| f[:avg_hit] }.reduce(:+)
@avg_hit = (sum / @files_count).round(2)
# Calculate number of relevant lines
@lines_total = files.map { |f| f[:lines_total] }.reduce(:+)
@lines_covered = files.map { |f| f[:lines_covered] }.reduce(:+)
@lines_relevant = files.map { |f| f[:lines_relevant] }.reduce(:+)
@lines_missed = files.map { |f| f[:lines_missed] }.reduce(:+)
# Calculate coverage percent
@coverage_percent = ((@lines_covered * 100.00) / @lines_relevant).round(2)
end
end
def to_hash
{
files_count: files_count,
coverage_percent: coverage_percent,
avg_hit: avg_hit,
lines_total: lines_total,
lines_relevant: lines_relevant,
lines_missed: lines_missed,
lines_covered: lines_covered,
files: files
}
end
private
def parse_element(el)
td = el.css("td")
{
file: el.css("a.src_link").children.first.text,
coverage_percent: Float(td[1].children.first.text.scan(/[\d\.]+/)[0]),
lines_total: Integer(td[2].children.first.text),
lines_relevant: Integer(td[3].children.first.text),
lines_covered: Integer(td[4].children.first.text),
lines_missed: Integer(td[5].children.first.text),
avg_hit: (Float(td[6].children.first.text) rescue 0.00)
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.