var coverIndex = 0
+// isTestFile reports whether the source file is a set of tests and should therefore
+// be excluded from coverage analysis.
+func isTestFile(file string) bool {
+ // We don't cover tests, only the code they test.
+ return strings.HasSuffix(file, "_test.go")
+}
+
// declareCoverVars attaches the required cover variables names
// to the files, to be used when annotating the files.
func declareCoverVars(importPath string, files ...string) map[string]*CoverVar {
coverVars := make(map[string]*CoverVar)
for _, file := range files {
+ if isTestFile(file) {
+ continue
+ }
coverVars[file] = &CoverVar{
File: filepath.Join(importPath, file),
Var: fmt.Sprintf("GoCover_%d", coverIndex),
if testShowPass {
a.testOutput.Write(out)
}
- coverWhere := ""
- if testCoverPaths != nil {
- coverWhere = " in " + strings.Join(testCoverPaths, ", ")
- }
- fmt.Fprintf(a.testOutput, "ok \t%s\t%s%s%s\n", a.p.ImportPath, t, coveragePercentage(out), coverWhere)
+ fmt.Fprintf(a.testOutput, "ok \t%s\t%s%s\n", a.p.ImportPath, t, coveragePercentage(out))
return nil
}
// The string looks like
// test coverage for encoding/binary: 79.9% of statements
// Extract the piece from the percentage to the end of the line.
- re := regexp.MustCompile(`test coverage for [^ ]+: (.*)\n`)
+ re := regexp.MustCompile(`coverage for [^ ]+: (.*)\n`)
matches := re.FindSubmatch(out)
if matches == nil {
- return "(missing coverage statistics)"
+ // Probably running "go test -cover" not "go test -cover fmt".
+ // The coverage output will appear in the output directly.
+ return ""
}
return fmt.Sprintf("\tcoverage: %s", matches[1])
}
return testCover
}
+// Covered returns a string describing which packages are being tested for coverage.
+// If the covered package is the same as the tested package, it returns the empty string.
+// Otherwise it is a comma-separated human-readable list of packages beginning with
+// " in", ready for use in the coverage message.
+func (t *testFuncs) Covered() string {
+ if testCoverPaths == nil {
+ return ""
+ }
+ return " in " + strings.Join(testCoverPaths, ", ")
+}
+
+// Tested returns the name of the package being tested.
+func (t *testFuncs) Tested() string {
+ return t.Package.Name
+}
+
type testFunc struct {
Package string // imported package name (_test or _xtest)
Name string // function name
panic("coverage: mismatched sizes")
}
if coverCounters[fileName] != nil {
- panic("coverage: duplicate counter array for " + fileName)
+ // Already registered.
+ return
}
coverCounters[fileName] = counter
block := make([]testing.CoverBlock, len(counter))
func main() {
{{if .CoverEnabled}}
+ testing.CoveredPackage({{printf "%q" .Tested}}, {{printf "%q" .Covered}})
testing.RegisterCover(coverCounters, coverBlocks)
{{end}}
testing.Main(matchString, tests, benchmarks, examples)
coverBlocks map[string][]CoverBlock
)
+var (
+ testedPackage string // The package being tested.
+ coveredPackage string // List of the package[s] being covered, if distinct from the tested package.
+)
+
// RegisterCover records the coverage data accumulators for the tests.
// NOTE: This struct is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
coverBlocks = b
}
+// CoveredPackage records the names of the packages being tested and covered.
+// NOTE: This function is internal to the testing infrastructure and may change.
+// It is not covered (yet) by the Go 1 compatibility guidelines.
+func CoveredPackage(tested, covered string) {
+ testedPackage = tested
+ coveredPackage = covered
+}
+
// mustBeNil checks the error and, if present, reports it and exits.
func mustBeNil(err error) {
if err != nil {
}
var active, total int64
- packageName := ""
for name, counts := range coverCounters {
- if packageName == "" {
- // Package name ends at last slash.
- for i, c := range name {
- if c == '/' {
- packageName = name[:i]
- }
- }
- }
blocks := coverBlocks[name]
for i, count := range counts {
stmts := int64(blocks[i].Stmts)
if total == 0 {
total = 1
}
- if packageName == "" {
- packageName = "package"
- }
- fmt.Printf("test coverage for %s: %.1f%% of statements\n", packageName, 100*float64(active)/float64(total))
+ fmt.Printf("coverage for %s: %.1f%% of statements%s\n", testedPackage, 100*float64(active)/float64(total), coveredPackage)
}