Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions pkg/testcoverage/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func Check(w io.Writer, cfg Config) bool {
}
}

err = generateAndSaveBadge(w, cfg, result.TotalCoverage)
err = generateAndSaveBadge(w, cfg, result.TotalStats.CoveredPercentage())
if err != nil {
fmt.Fprintf(w, "failed to generate and save badge: %v\n", err)
return false
Expand All @@ -58,23 +58,14 @@ func reportForHuman(w io.Writer, result AnalyzeResult) string {

func Analyze(cfg Config, coverageStats []coverage.Stats) AnalyzeResult {
thr := cfg.Threshold

overrideRules := compileOverridePathRules(cfg)

filesBelowThreshold := checkCoverageStatsBelowThreshold(coverageStats, thr.File, overrideRules)

packagesBelowThreshold := checkCoverageStatsBelowThreshold(
makePackageStats(coverageStats), thr.Package, overrideRules,
)

totalStats := coverage.CalcTotalStats(coverageStats)
meetsTotalCoverage := len(coverageStats) == 0 || totalStats.CoveredPercentage() >= thr.Total

return AnalyzeResult{
Threshold: thr,
FilesBelowThreshold: filesBelowThreshold,
PackagesBelowThreshold: packagesBelowThreshold,
MeetsTotalCoverage: meetsTotalCoverage,
TotalCoverage: totalStats.CoveredPercentage(),
Threshold: thr,
FilesBelowThreshold: checkCoverageStatsBelowThreshold(coverageStats, thr.File, overrideRules),
PackagesBelowThreshold: checkCoverageStatsBelowThreshold(
makePackageStats(coverageStats), thr.Package, overrideRules,
),
TotalStats: coverage.CalcTotalStats(coverageStats),
}
}
2 changes: 1 addition & 1 deletion pkg/testcoverage/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func Test_Analyze(t *testing.T) {
result := Analyze(Config{}, nil)
assert.Empty(t, result.FilesBelowThreshold)
assert.Empty(t, result.PackagesBelowThreshold)
assert.Equal(t, 0, result.TotalCoverage)
assert.Equal(t, 0, result.TotalStats.CoveredPercentage())
})

t.Run("total coverage above threshold", func(t *testing.T) {
Expand Down
20 changes: 19 additions & 1 deletion pkg/testcoverage/coverage/types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package coverage

import (
"fmt"
"regexp"
"strings"
)
Expand All @@ -17,7 +18,24 @@ func (s Stats) CoveredPercentage() int {
}

//nolint:mnd // relax
func (s Stats) Str() string {
c := s.CoveredPercentage()

if c == 100 { // precision not needed
return fmt.Sprintf("%d%% (%d/%d)", c, s.Covered, s.Total)
} else if c < 10 { // adds space for singe digit number
return fmt.Sprintf(" %.1f%% (%d/%d)", coveredPercentageF(s.Total, s.Covered), s.Covered, s.Total)
}

return fmt.Sprintf("%.1f%% (%d/%d)", coveredPercentageF(s.Total, s.Covered), s.Covered, s.Total)
}

func CoveredPercentage(total, covered int64) int {
return int(coveredPercentageF(total, covered))
}

//nolint:mnd // relax
func coveredPercentageF(total, covered int64) float64 {
if total == 0 {
return 0
}
Expand All @@ -26,7 +44,7 @@ func CoveredPercentage(total, covered int64) int {
return 100
}

return int(float64(covered*100) / float64(total))
return float64(covered*100) / float64(total)
}

func stripPrefix(name, prefix string) string {
Expand Down
9 changes: 9 additions & 0 deletions pkg/testcoverage/coverage/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ func TestCoveredPercentage(t *testing.T) {
assert.Equal(t, tc.percentage, CoveredPercentage(tc.total, tc.covered))
}
}

func TestStatStr(t *testing.T) {
t.Parallel()

assert.Equal(t, " 0.0% (0/0)", Stats{}.Str())
assert.Equal(t, " 9.1% (1/11)", Stats{Covered: 1, Total: 11}.Str())
assert.Equal(t, "22.2% (2/9)", Stats{Covered: 2, Total: 9}.Str())
assert.Equal(t, "100% (10/10)", Stats{Covered: 10, Total: 10}.Str())
}
24 changes: 12 additions & 12 deletions pkg/testcoverage/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ func ReportForHuman(w io.Writer, result AnalyzeResult) {

if thr.Total > 0 { // Total threshold report
fmt.Fprintf(tabber, "Total coverage threshold (%d%%) satisfied:\t", thr.Total)
fmt.Fprint(tabber, statusStr(result.MeetsTotalCoverage))
fmt.Fprint(tabber, statusStr(result.MeetsTotalCoverage()))
fmt.Fprint(tabber, "\n")
}

fmt.Fprintf(tabber, "Total test coverage: %d%%\n", result.TotalCoverage)
fmt.Fprintf(tabber, "Total test coverage: %s\n", result.TotalStats.Str())
}

func reportIssuesForHuman(w io.Writer, coverageStats []coverage.Stats) {
Expand All @@ -62,7 +62,7 @@ func reportIssuesForHuman(w io.Writer, coverageStats []coverage.Stats) {
fmt.Fprintf(w, "\n below threshold:\tcoverage:\tthreshold:")

for _, stats := range coverageStats {
fmt.Fprintf(w, "\n %s\t%d%%\t%d%%", stats.Name, stats.CoveredPercentage(), stats.Threshold)
fmt.Fprintf(w, "\n %s\t%s\t%d%%", stats.Name, stats.Str(), stats.Threshold)
}

fmt.Fprintf(w, "\n")
Expand All @@ -82,26 +82,26 @@ func ReportForGithubAction(w io.Writer, result AnalyzeResult) {
for _, stats := range result.FilesBelowThreshold {
title := "File test coverage below threshold"
msg := fmt.Sprintf(
"%s: coverage: %d%%; threshold: %d%%",
title, stats.CoveredPercentage(), stats.Threshold,
"%s: coverage: %s; threshold: %d%%",
title, stats.Str(), stats.Threshold,
)
reportLineError(stats.Name, title, msg)
}

for _, stats := range result.PackagesBelowThreshold {
title := "Package test coverage below threshold"
msg := fmt.Sprintf(
"%s: package: %s; coverage: %d%%; threshold: %d%%",
title, stats.Name, stats.CoveredPercentage(), stats.Threshold,
"%s: package: %s; coverage: %s; threshold: %d%%",
title, stats.Name, stats.Str(), stats.Threshold,
)
reportError(title, msg)
}

if !result.MeetsTotalCoverage {
if !result.MeetsTotalCoverage() {
title := "Total test coverage below threshold"
msg := fmt.Sprintf(
"%s: coverage: %d%%; threshold: %d%%",
title, result.TotalCoverage, result.Threshold.Total,
"%s: coverage: %s; threshold: %d%%",
title, result.TotalStats.Str(), result.Threshold.Total,
)
reportError(title, msg)
}
Expand All @@ -121,11 +121,11 @@ func SetGithubActionOutput(result AnalyzeResult, report string) error {
return fmt.Errorf("could not open GitHub output file: %w", err)
}

totalStr := strconv.Itoa(result.TotalCoverage)
totalStr := strconv.Itoa(result.TotalStats.CoveredPercentage())

return errors.Join(
setOutputValue(file, gaOutputTotalCoverage, totalStr),
setOutputValue(file, gaOutputBadgeColor, badge.Color(result.TotalCoverage)),
setOutputValue(file, gaOutputBadgeColor, badge.Color(result.TotalStats.CoveredPercentage())),
setOutputValue(file, gaOutputBadgeText, totalStr+"%"),
setOutputValue(file, gaOutputReport, multiline(report)),
file.Close(),
Expand Down
5 changes: 3 additions & 2 deletions pkg/testcoverage/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/assert"

. "github.com/vladopajic/go-test-coverage/v2/pkg/testcoverage"
"github.com/vladopajic/go-test-coverage/v2/pkg/testcoverage/coverage"
)

func Test_ReportForHuman(t *testing.T) {
Expand All @@ -22,15 +23,15 @@ func Test_ReportForHuman(t *testing.T) {
t.Parallel()

buf := &bytes.Buffer{}
ReportForHuman(buf, AnalyzeResult{Threshold: thr, MeetsTotalCoverage: true})
ReportForHuman(buf, AnalyzeResult{Threshold: thr, TotalStats: coverage.Stats{}})
assertHumanReport(t, buf.String(), 3, 0)
})

t.Run("total coverage - fail", func(t *testing.T) {
t.Parallel()

buf := &bytes.Buffer{}
ReportForHuman(buf, AnalyzeResult{Threshold: thr, MeetsTotalCoverage: false})
ReportForHuman(buf, AnalyzeResult{Threshold: thr, TotalStats: coverage.Stats{Total: 1}})
assertHumanReport(t, buf.String(), 2, 1)
})

Expand Down
9 changes: 6 additions & 3 deletions pkg/testcoverage/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@ type AnalyzeResult struct {
Threshold Threshold
FilesBelowThreshold []coverage.Stats
PackagesBelowThreshold []coverage.Stats
MeetsTotalCoverage bool
TotalCoverage int
TotalStats coverage.Stats
}

func (r *AnalyzeResult) Pass() bool {
return r.MeetsTotalCoverage &&
return r.MeetsTotalCoverage() &&
len(r.FilesBelowThreshold) == 0 &&
len(r.PackagesBelowThreshold) == 0
}

func (r *AnalyzeResult) MeetsTotalCoverage() bool {
return r.TotalStats.Total == 0 || r.TotalStats.CoveredPercentage() >= r.Threshold.Total
}

func packageForFile(filename string) string {
i := strings.LastIndex(filename, "/")
if i == -1 {
Expand Down
Loading