Adding forgotten coverage helpers.
This commit is contained in:
parent
cd7f4d69f1
commit
bb0c91683f
2 changed files with 115 additions and 0 deletions
98
tools/testtool/commands/coverage.go
Normal file
98
tools/testtool/commands/coverage.go
Normal file
|
@ -0,0 +1,98 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/cover"
|
||||
)
|
||||
|
||||
// coverageCommentPrefix is a prefix of coverage comment.
|
||||
//
|
||||
// Coverage comment has the following form:
|
||||
//
|
||||
// // min coverage: 80.5%
|
||||
const coverageCommentPrefix = "min coverage: "
|
||||
|
||||
type CoverageRequirements struct {
|
||||
Enabled bool
|
||||
Percent float64
|
||||
}
|
||||
|
||||
// getCoverageRequirements searches for comment in test files
|
||||
// that specifies test coverage requirements.
|
||||
//
|
||||
// Stops on first matching comment.
|
||||
func getCoverageRequirements(rootPackage string) *CoverageRequirements {
|
||||
files := listTestFiles(rootPackage)
|
||||
|
||||
r := &CoverageRequirements{}
|
||||
for _, f := range files {
|
||||
r, _ := searchCoverageComment(f)
|
||||
if r.Enabled {
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// searchCoverageComment searches for the first occurrence of the comment of the form
|
||||
//
|
||||
// // min coverage: 80.5%
|
||||
//
|
||||
// Stops on the first matching comment.
|
||||
func searchCoverageComment(fname string) (*CoverageRequirements, error) {
|
||||
fset := token.NewFileSet()
|
||||
|
||||
f, err := parser.ParseFile(fset, fname, nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, c := range f.Comments {
|
||||
t := c.Text()
|
||||
if !strings.HasPrefix(t, coverageCommentPrefix) || !strings.HasSuffix(t, "%\n") {
|
||||
continue
|
||||
}
|
||||
t = strings.TrimPrefix(t, coverageCommentPrefix)
|
||||
t = strings.TrimSuffix(t, "%\n")
|
||||
percent, err := strconv.ParseFloat(t, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if percent < 0 || percent > 100.0 {
|
||||
continue
|
||||
}
|
||||
return &CoverageRequirements{Enabled: true, Percent: percent}, nil
|
||||
}
|
||||
|
||||
return &CoverageRequirements{}, nil
|
||||
}
|
||||
|
||||
// calCoverage calculates coverage percent for given coverage profile.
|
||||
func calCoverage(profile string) (float64, error) {
|
||||
profiles, err := cover.ParseProfiles(profile)
|
||||
if err != nil {
|
||||
return 0.0, fmt.Errorf("cannot parse coverage profile file %s: %w", profile, err)
|
||||
}
|
||||
|
||||
var total, covered int
|
||||
for _, p := range profiles {
|
||||
for _, block := range p.Blocks {
|
||||
total += block.NumStmt
|
||||
if block.Count > 0 {
|
||||
covered += block.NumStmt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if total == 0 {
|
||||
return 0.0, nil
|
||||
}
|
||||
|
||||
return float64(covered) / float64(total) * 100, nil
|
||||
}
|
17
tools/testtool/commands/coverage_test.go
Normal file
17
tools/testtool/commands/coverage_test.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_getCoverageRequirements(t *testing.T) {
|
||||
r := getCoverageRequirements("../testdata/coverage/sum")
|
||||
require.True(t, r.Enabled)
|
||||
require.Equal(t, 90.0, r.Percent)
|
||||
t.Logf("r: %+v", r)
|
||||
//require.Equal(t,
|
||||
// absPaths([]string{"sum/private_test.go", "sum/public_test.go"}),
|
||||
// getCoverageRequirements("../testdata/coverage"))
|
||||
}
|
Loading…
Reference in a new issue