forked from JohnStarich/go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
summary.go
81 lines (72 loc) · 2.61 KB
/
summary.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package covet
import (
"io"
"sort"
"github.com/johnstarich/go/covet/internal/summary"
)
// ReportSummaryOptions contains summary report options
type ReportSummaryOptions struct {
Target uint
}
// ReportSummaryMarkdown writes a markdown report to 'w'.
// To capture as a string, write to a bytes.Buffer, then call buf.String().
func (c *Covet) ReportSummaryMarkdown(w io.Writer, options ReportSummaryOptions) error {
return c.reportSummary(w, options, summary.FormatMarkdown)
}
// ReportSummaryColorTerminal writes a plain text report with color to 'w'.
func (c *Covet) ReportSummaryColorTerminal(w io.Writer, options ReportSummaryOptions) error {
return c.reportSummary(w, options, summary.FormatColorTerminal)
}
func (c *Covet) reportSummary(w io.Writer, options ReportSummaryOptions, format summary.Format) error {
uncoveredFiles := c.PriorityUncoveredFiles(options.Target)
report := summary.New(uncoveredFiles, options.Target, format)
_, err := io.WriteString(w, report)
return err
}
// PriorityUncoveredFiles returns a list of Files prioritized by the largest uncovered sections of the diff.
// The list contains just enough Files worth of uncovered lines necessary to meet the provided 'target' coverage.
func (c *Covet) PriorityUncoveredFiles(target uint) []File {
coveredFiles := c.DiffCoverageFiles()
const maxPercentInt = 100
targetPercent := float64(target) / maxPercentInt
current := c.DiffCovered()
return findReportableUncoveredFiles(coveredFiles, targetPercent, current)
}
func findReportableUncoveredFiles(coveredFiles []File, target, current float64) []File {
// sort by highest uncovered line count
sort.Slice(coveredFiles, func(aIndex, bIndex int) bool {
a, b := coveredFiles[aIndex], coveredFiles[bIndex]
switch {
case a.Uncovered != b.Uncovered:
return a.Uncovered > b.Uncovered
default:
return a.Name < b.Name
}
})
var uncoveredFiles []File
// find minimum number of covered lines required to hit target
targetMissingLines := 0
totalLines := uint(0)
for _, f := range coveredFiles {
totalLines += f.Covered + f.Uncovered
}
if percentDiff := target - current; percentDiff > 0 {
targetMissingLines = int(percentDiff * float64(totalLines))
} else {
return nil // target is met
}
// next, collect the biggest uncovered files until we'd hit the target
for _, f := range coveredFiles {
const minUncoveredThreshold = 2 // include more files if it is slim pickings
if f.Uncovered > 0 {
uncoveredFiles = append(uncoveredFiles, f)
}
if f.Uncovered > minUncoveredThreshold {
targetMissingLines -= int(f.Uncovered)
}
if targetMissingLines <= 0 {
break
}
}
return uncoveredFiles
}