covhura 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/covhura.rb +5 -0
- data/lib/covhura.rb +82 -0
- data/lib/report/clover.rb +20 -0
- data/lib/report/cobertura.rb +20 -0
- data/lib/report/lcov.rb +77 -0
- data/lib/report/simplecov.rb +33 -0
- data/lib/report.rb +2 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cf3df102e2f0a35ce06e33bca52a82744a522968
|
4
|
+
data.tar.gz: 23410c79deefd695d11625cd95e4e2168262c982
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e77c29aba5b090b40754cd4e7b4b159ee32961cb8e993408fe970b6d8e444448b493a55f04bea0450b782c440e6a96df63699bb6141e555338278461b34ecd3e
|
7
|
+
data.tar.gz: 356c62803069ea720f097de41641bc0be5d3abc38734f9b11765595979bafbda70fab33ee5853e4b62e350d02061ae58ae86250c1fca8811288784887398dcf3
|
data/bin/covhura.rb
ADDED
data/lib/covhura.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require "json"
|
2
|
+
require "nokogiri"
|
3
|
+
|
4
|
+
require_relative "report"
|
5
|
+
require_relative "report/clover"
|
6
|
+
require_relative "report/lcov"
|
7
|
+
require_relative "report/cobertura"
|
8
|
+
require_relative "report/simplecov"
|
9
|
+
|
10
|
+
class Covhura
|
11
|
+
def translate(doc)
|
12
|
+
lines = doc.lines
|
13
|
+
first_line = lines
|
14
|
+
.detect { |line| line.strip() != "" }
|
15
|
+
.strip()
|
16
|
+
|
17
|
+
if xml?(doc)
|
18
|
+
doc = Nokogiri::XML(doc)
|
19
|
+
if clover?(doc)
|
20
|
+
translator = Report::Clover
|
21
|
+
elsif cobertura?(doc)
|
22
|
+
translator = Report::Cobertura
|
23
|
+
end
|
24
|
+
elsif json?(first_line)
|
25
|
+
doc = JSON.parse(doc)
|
26
|
+
translator = Report::SimpleCov
|
27
|
+
elsif lcov?(first_line)
|
28
|
+
translator = Report::LCov
|
29
|
+
end
|
30
|
+
|
31
|
+
raise "Coverage Format Not Supported" if !defined?(translator) || translator.nil?
|
32
|
+
|
33
|
+
translator.new.translate(doc)
|
34
|
+
end
|
35
|
+
|
36
|
+
def merge(old, new)
|
37
|
+
new.reduce(old) do |acc, (file_path, file_coverage)|
|
38
|
+
acc[file_path] ||= {}
|
39
|
+
acc[file_path][:lines] ||= {}
|
40
|
+
|
41
|
+
old_coverage = acc.dig(file_path, :lines)
|
42
|
+
|
43
|
+
file_coverage[:lines].each do |line_number, line|
|
44
|
+
acc[file_path][:lines][line_number] = old_coverage.has_key?(line_number) ?
|
45
|
+
merge_line(old_coverage[line_number], line) :
|
46
|
+
line
|
47
|
+
end
|
48
|
+
|
49
|
+
acc
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def clover?(doc)
|
56
|
+
doc.xpath("/coverage")&.attr("clover") != nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def cobertura?(doc)
|
60
|
+
doc.internal_subset.to_s.match(/cobertura/i) != nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def xml?(first_line)
|
64
|
+
first_line[0...5] == "<?xml"
|
65
|
+
end
|
66
|
+
|
67
|
+
def json?(first_line)
|
68
|
+
first_line[0] == "{" || first_line[0] == "["
|
69
|
+
end
|
70
|
+
|
71
|
+
def lcov?(first_line)
|
72
|
+
first_line[0...3] == "TN:"
|
73
|
+
end
|
74
|
+
|
75
|
+
def merge_line(old, new)
|
76
|
+
{
|
77
|
+
number: old[:number],
|
78
|
+
hits: (old[:hits] || 0) + (new[:hits] || 0),
|
79
|
+
type: old[:type] || new[:type]
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Report::Clover
|
2
|
+
def translate(doc)
|
3
|
+
doc
|
4
|
+
.xpath("//file")
|
5
|
+
.reduce({}) do |acc, file|
|
6
|
+
acc[file.attr("path")] ||= {}
|
7
|
+
acc[file.attr("path")][:lines] = file
|
8
|
+
.xpath("line")
|
9
|
+
.reduce({}) do |bcc, line|
|
10
|
+
line_num = line.attr("num").to_i
|
11
|
+
bcc[line_num] = {
|
12
|
+
hits: line.attr("count").to_i,
|
13
|
+
type: line.attr("type") == "cond" ? :condition : :statement
|
14
|
+
}
|
15
|
+
bcc
|
16
|
+
end
|
17
|
+
acc
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Report::Cobertura
|
2
|
+
def translate(doc)
|
3
|
+
doc
|
4
|
+
.xpath("//class")
|
5
|
+
.reduce({}) do |acc, file|
|
6
|
+
acc[file.attr("filename")] ||= {}
|
7
|
+
acc[file.attr("filename")][:lines] = file
|
8
|
+
.xpath("lines/line")
|
9
|
+
.reduce({}) do |bcc, line|
|
10
|
+
line_num = line.attr("number").to_i
|
11
|
+
bcc[line_num] = {
|
12
|
+
hits: line.attr("hits").to_i,
|
13
|
+
type: line.attr("branch") == "true" ? :condition : :statement
|
14
|
+
}
|
15
|
+
bcc
|
16
|
+
end
|
17
|
+
acc
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/report/lcov.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# TN: -> start of record
|
2
|
+
# SF: -> file path
|
3
|
+
# FN: -> function declaration (line#,func_name)
|
4
|
+
# FNDA: function coverage (count,func_name)
|
5
|
+
# BRDA: branch coverage (line#,block#,branch#,count) count = - for none
|
6
|
+
# DA: line coverage
|
7
|
+
# LF: statements
|
8
|
+
# LH: statements covered
|
9
|
+
# FNF: functions
|
10
|
+
# FNH: functions covered
|
11
|
+
# BRF: branches / conditionals
|
12
|
+
# BRH: branches / conditions covered
|
13
|
+
# end_of_record: -> end of record
|
14
|
+
class Report::LCov
|
15
|
+
def translate(doc)
|
16
|
+
files(doc).reduce({}) do |acc, file|
|
17
|
+
file.shift()
|
18
|
+
|
19
|
+
lines = lines(file)
|
20
|
+
branches = branches(file)
|
21
|
+
|
22
|
+
path = file.first[3..-1]
|
23
|
+
acc[path] = {lines: merge(lines, branches)}
|
24
|
+
|
25
|
+
acc
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def files(doc)
|
32
|
+
files = doc
|
33
|
+
.lines
|
34
|
+
.map(&:chomp)
|
35
|
+
.reduce([[]]) do |acc, line|
|
36
|
+
if line == "end_of_record"
|
37
|
+
acc << []
|
38
|
+
else
|
39
|
+
acc.last << line
|
40
|
+
end
|
41
|
+
acc
|
42
|
+
end
|
43
|
+
files.pop()
|
44
|
+
files
|
45
|
+
end
|
46
|
+
|
47
|
+
def lines(file)
|
48
|
+
file.reduce({}) do |acc, line|
|
49
|
+
if line[0...3] == "DA:"
|
50
|
+
coverage = line[3..-1].split(",")
|
51
|
+
acc[coverage.first.to_i] = coverage.last.to_i
|
52
|
+
end
|
53
|
+
acc
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def branches(file)
|
58
|
+
file.reduce({}) do |acc, line|
|
59
|
+
if line[0...5] == "BRDA:"
|
60
|
+
coverage = line[5..-1].split(",")
|
61
|
+
acc[coverage.first.to_i] = true
|
62
|
+
end
|
63
|
+
acc
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# TODO: Technically this misses branches that aren't covered in DA.
|
68
|
+
def merge(lines, branches)
|
69
|
+
lines.reduce({}) do |acc, (num, count)|
|
70
|
+
acc[num] = {
|
71
|
+
hits: count,
|
72
|
+
type: branches.has_key?(num) ? :condition : :statement
|
73
|
+
}
|
74
|
+
acc
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Report::SimpleCov
|
2
|
+
def translate(json)
|
3
|
+
json
|
4
|
+
.reduce({}) do |acc, (_test_runner, results)|
|
5
|
+
results["coverage"].each do |file_path, file_coverage|
|
6
|
+
acc[file_path] ||= {}
|
7
|
+
file_coverage.each_with_index do |line_coverage, i|
|
8
|
+
line_num = i + 1
|
9
|
+
if line_coverage.nil?
|
10
|
+
acc[file_path][line_num] = nil
|
11
|
+
next
|
12
|
+
end
|
13
|
+
old_coverage = acc[file_path][line_num]
|
14
|
+
acc[file_path][line_num] = old_coverage.nil? ?
|
15
|
+
line_coverage :
|
16
|
+
line_coerage + old_coverage
|
17
|
+
end
|
18
|
+
end
|
19
|
+
acc
|
20
|
+
end
|
21
|
+
.reduce({}) do |acc, (file_name, lines)|
|
22
|
+
acc[file_name] ||= {}
|
23
|
+
acc[file_name][:lines] = lines.reduce({}) do |bcc, (line_num, hits)|
|
24
|
+
bcc[line_num] = {
|
25
|
+
hits: hits,
|
26
|
+
type: :unknown
|
27
|
+
}
|
28
|
+
bcc
|
29
|
+
end
|
30
|
+
acc
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/report.rb
ADDED
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: covhura
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Yahn
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-10-31 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Translate code coverage reports into a universal format.
|
14
|
+
email: yahn007@outlook.com
|
15
|
+
executables:
|
16
|
+
- covhura.rb
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/covhura.rb
|
21
|
+
- lib/covhura.rb
|
22
|
+
- lib/report.rb
|
23
|
+
- lib/report/clover.rb
|
24
|
+
- lib/report/cobertura.rb
|
25
|
+
- lib/report/lcov.rb
|
26
|
+
- lib/report/simplecov.rb
|
27
|
+
homepage: https://github.com/cuzzo/covhura
|
28
|
+
licenses:
|
29
|
+
- BSD-2-Clause
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubyforge_project:
|
47
|
+
rubygems_version: 2.5.2
|
48
|
+
signing_key:
|
49
|
+
specification_version: 4
|
50
|
+
summary: Coverage Report Translation
|
51
|
+
test_files: []
|