Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix coverage detection for go1.20 #325

Merged
merged 1 commit into from Jun 9, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 18 additions & 6 deletions testjson/execution.go
Expand Up @@ -365,8 +365,8 @@ func (p *Package) addEvent(event TestEvent) {
p.action = event.Action
p.elapsed = elapsedDuration(event.Elapsed)
case ActionOutput:
if isCoverageOutput(event.Output) {
p.coverage = strings.TrimRight(event.Output, "\n")
if coverage, ok := isCoverageOutput(event.Output); ok {
p.coverage = coverage
}
if strings.Contains(event.Output, "\t(cached)") {
p.cached = true
Expand Down Expand Up @@ -466,10 +466,22 @@ func elapsedDuration(elapsed float64) time.Duration {
return time.Duration(elapsed*1000) * time.Millisecond
}

func isCoverageOutput(output string) bool {
return all(
strings.HasPrefix(output, "coverage:"),
strings.Contains(output, "% of statements"))
func isCoverageOutput(output string) (string, bool) {
start := strings.Index(output, "coverage:")
if start < 0 {
return "", false
}

if !strings.Contains(output[start:], "% of statements") {
return "", false
}

return strings.TrimRight(output[start:], "\n"), true
}

func isCoverageOutputPreGo119(output string) bool {
return strings.HasPrefix(output, "coverage:") &&
strings.HasSuffix(output, "% of statements\n")
}

func isShuffleSeedOutput(output string) bool {
Expand Down
11 changes: 10 additions & 1 deletion testjson/format.go
Expand Up @@ -41,9 +41,18 @@ func standardQuietFormat(out io.Writer) EventFormatter {
if !event.PackageEvent() {
return nil
}
if event.Output == "PASS\n" || isCoverageOutput(event.Output) {
if event.Output == "PASS\n" {
return nil
}

// Coverage line go1.20+
if strings.Contains(event.Output, event.Package+"\tcoverage:") {
return nil
}
if isCoverageOutputPreGo119(event.Output) {
return nil
}

if isWarningNoTestsToRunOutput(event.Output) {
return nil
}
Expand Down
25 changes: 22 additions & 3 deletions testjson/format_test.go
Expand Up @@ -145,6 +145,7 @@ func TestFormats_Coverage(t *testing.T) {
type testCase struct {
name string
format func(writer io.Writer) EventFormatter
input string
expectedOut string
expected func(t *testing.T, exec *Execution)
}
Expand All @@ -153,7 +154,11 @@ func TestFormats_Coverage(t *testing.T) {
patchPkgPathPrefix(t, "gotest.tools")
out := new(bytes.Buffer)

shim := newFakeHandler(tc.format(out), "input/go-test-json-with-cover")
if tc.input == "" {
tc.input = "input/go-test-json-with-cover"
}

shim := newFakeHandler(tc.format(out), tc.input)
exec, err := ScanTestOutput(shim.Config(t))
assert.NilError(t, err)

Expand All @@ -172,7 +177,7 @@ func TestFormats_Coverage(t *testing.T) {
expectedOut: "format/testname-coverage.out",
},
{
name: "pkgname",
name: "pkgname go1.19-",
format: func(out io.Writer) EventFormatter {
return pkgNameFormat(out, FormatOptions{})
},
Expand All @@ -184,10 +189,24 @@ func TestFormats_Coverage(t *testing.T) {
expectedOut: "format/standard-verbose-coverage.out",
},
{
name: "standard-quiet",
name: "standard-quiet go1.19-",
format: standardQuietFormat,
expectedOut: "format/standard-quiet-coverage.out",
},
{
name: "pkgname go1.20+",
format: func(out io.Writer) EventFormatter {
return pkgNameFormat(out, FormatOptions{})
},
input: "input/go-test-json-with-cover-go1.20",
expectedOut: "format/pkgname-coverage-go1.20.out",
},
{
name: "standard-quiet go.20+",
format: standardQuietFormat,
input: "input/go-test-json-with-cover-go1.20",
expectedOut: "format/standard-quiet-coverage-go1.20.out",
},
}

for _, tc := range testCases {
Expand Down
11 changes: 11 additions & 0 deletions testjson/internal/good/good.go
@@ -0,0 +1,11 @@
//go:build stubpkg
// +build stubpkg

package good

func Something() int {
for i := 0; i < 10; i++ {
return i
}
return 0
}
2 changes: 2 additions & 0 deletions testjson/internal/good/good_test.go
@@ -1,3 +1,4 @@
//go:build stubpkg
// +build stubpkg

package good
Expand All @@ -12,6 +13,7 @@ import (
func TestPassed(t *testing.T) {}

func TestPassedWithLog(t *testing.T) {
Something()
t.Log("this is a log")
}

Expand Down
5 changes: 5 additions & 0 deletions testjson/testdata/format/pkgname-coverage-go1.20.out
@@ -0,0 +1,5 @@
✖ gotestsum/testjson/internal/badmain (1ms)
∅ gotestsum/testjson/internal/empty (cached)
✓ gotestsum/testjson/internal/good (20ms) (coverage: 66.7% of statements)
✖ gotestsum/testjson/internal/parallelfails (21ms)
✖ gotestsum/testjson/internal/withfails (20ms)
11 changes: 11 additions & 0 deletions testjson/testdata/format/standard-quiet-coverage-go1.20.out
@@ -0,0 +1,11 @@
sometimes main can exit 2
program not built with -cover
FAIL gotest.tools/gotestsum/testjson/internal/badmain 0.001s
ok gotest.tools/gotestsum/testjson/internal/empty (cached) coverage: [no statements] [no tests to run]
ok gotest.tools/gotestsum/testjson/internal/good 0.020s coverage: 66.7% of statements
FAIL
coverage: [no statements]
FAIL gotest.tools/gotestsum/testjson/internal/parallelfails 0.021s
FAIL
coverage: [no statements]
FAIL gotest.tools/gotestsum/testjson/internal/withfails 0.020s
2 changes: 2 additions & 0 deletions testjson/testdata/input/go-test-json-with-cover-go1.20.err
@@ -0,0 +1,2 @@
# gotest.tools/gotestsum/testjson/internal/broken
internal/broken/broken.go:5:21: undefined: somepackage