From 6c886cf6a3422d88b71750a561f46d9ac2c5d4ea Mon Sep 17 00:00:00 2001 From: Janos Bonic <86970079+janosdebugs@users.noreply.github.com> Date: Sun, 5 Dec 2021 13:38:03 +0100 Subject: [PATCH] Fixes #8: Support for JSON test output (#9) --- .circleci/config.yml | 6 +- .github/workflows/build.yaml | 4 +- .gitlab-ci.yml | 2 +- .gotestfmt/package.gotpl | 1 - README.md | 12 +- _testsource/coverage/code.go | 5 + _testsource/coverage/code_test.go | 13 + _testsource/coverage/go.mod | 4 + cmd/gotestfmt/main.go | 22 +- parser/model.go | 10 +- parser/parse.go | 503 ++++++++++-------- testdata/coverage-nostatements.parser.json | 2 +- testdata/coverage-nostatements.tokenizer.json | 19 +- testdata/coverage-nostatements.txt | 13 +- testdata/coverage.parser.json | 5 +- testdata/coverage.tokenizer.json | 27 +- testdata/coverage.txt | 13 +- testdata/gotestfmt.parser.json | 63 --- testdata/gotestfmt.tokenizer.json | 72 --- testdata/gotestfmt.txt | 6 - testdata/misattribution.parser.json | 35 -- testdata/misattribution.txt | 7 - testdata/mod-download.parser.json | 2 +- testdata/mod-download.tokenizer.json | 15 +- testdata/mod-download.txt | 11 +- testdata/multipackage-syntax-json.parser.json | 32 ++ ...> multipackage-syntax-json.tokenizer.json} | 50 +- testdata/multipackage-syntax-json.txt | 10 + testdata/parallel.parser.json | 6 +- testdata/parallel.tokenizer.json | 148 +++++- testdata/parallel.txt | 43 +- testdata/single-package-verbose.parser.json | 18 - .../single-package-verbose.tokenizer.json | 18 - testdata/single-package-verbose.txt | 4 - testdata/single-package.parser.json | 12 - testdata/single-package.tokenizer.json | 7 - testdata/single-package.txt | 1 - testdata/skip.parser.json | 24 + testdata/skip.tokenizer.json | 46 ++ testdata/skip.txt | 7 + testdata/subtest.parser.json | 2 +- testdata/subtest.tokenizer.json | 57 +- testdata/subtest.txt | 36 +- testdata/testify.parser.json | 4 +- testdata/testify.tokenizer.json | 92 ++-- testdata/testify.txt | 23 +- testdata/testifymultipackage.parser.json | 16 +- testdata/testifymultipackage.tokenizer.json | 137 +++-- testdata/testifymultipackage.txt | 31 +- tokenizer/event.go | 7 + tokenizer/tokenizer.go | 67 ++- 51 files changed, 1049 insertions(+), 721 deletions(-) create mode 100644 _testsource/coverage/code.go create mode 100644 _testsource/coverage/code_test.go create mode 100644 _testsource/coverage/go.mod delete mode 100644 testdata/gotestfmt.parser.json delete mode 100644 testdata/gotestfmt.tokenizer.json delete mode 100644 testdata/gotestfmt.txt delete mode 100644 testdata/misattribution.parser.json delete mode 100644 testdata/misattribution.txt create mode 100644 testdata/multipackage-syntax-json.parser.json rename testdata/{misattribution.tokenizer.json => multipackage-syntax-json.tokenizer.json} (50%) create mode 100644 testdata/multipackage-syntax-json.txt delete mode 100644 testdata/single-package-verbose.parser.json delete mode 100644 testdata/single-package-verbose.tokenizer.json delete mode 100644 testdata/single-package-verbose.txt delete mode 100644 testdata/single-package.parser.json delete mode 100644 testdata/single-package.tokenizer.json delete mode 100644 testdata/single-package.txt create mode 100644 testdata/skip.parser.json create mode 100644 testdata/skip.tokenizer.json create mode 100644 testdata/skip.txt diff --git a/.circleci/config.yml b/.circleci/config.yml index 757704f..63c6570 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,10 +7,10 @@ jobs: - checkout - run: name: Self-test - command: go test ./... 2>&1 | go run cmd/gotestfmt/main.go + command: go test -json ./... 2>&1 | go run cmd/gotestfmt/main.go - run: name: Self-test (verbose) - command: go test -v ./... 2>&1 | tee /tmp/gotest.log | go run cmd/gotestfmt/main.go + command: go test -json -v ./... 2>&1 | tee /tmp/gotest.log | go run cmd/gotestfmt/main.go - store_artifacts: path: /tmp/gotest.log destination: gotest.log @@ -23,7 +23,7 @@ jobs: version: 19.03.13 - run: name: Container test - command: go test -v ./... 2>&1 | docker run -i ghcr.io/haveyoudebuggedit/gotestfmt:latest + command: go test -json -v ./... 2>&1 | docker run -i ghcr.io/haveyoudebuggedit/gotestfmt:latest workflows: version: 2 build-workflow: diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 67294b7..d7dd2a3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -97,11 +97,11 @@ jobs: - name: Run self-test run: | set -euo pipefail - go test ./... 2>&1 | tee /tmp/gotest.log | go run ./cmd/gotestfmt + go test -json ./... 2>&1 | tee /tmp/gotest.log | go run ./cmd/gotestfmt - name: Run self-test (verbose) run: | set -euo pipefail - go test -v ./... 2>&1 | tee /tmp/gotest-verbose.log | go run ./cmd/gotestfmt + go test -json -v ./... 2>&1 | tee /tmp/gotest-verbose.log | go run ./cmd/gotestfmt - name: Upload test log uses: actions/upload-artifact@v2 with: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 33e84fc..1833297 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,7 +13,7 @@ docker-build: --name gotestfmt-$$ \ -e GITLAB_CI=${GITLAB_CI} \ gotestfmt \ - /bin/sh -c "cd /source; go test -v ./... 2>&1 | tee /tmp/gotest.log | go run cmd/gotestfmt/main.go" + /bin/sh -c "cd /source; go test -json -v ./... 2>&1 | tee /tmp/gotest.log | go run cmd/gotestfmt/main.go" docker cp gotestfmt-$$:/tmp/gotest.log gotest.log docker rm --force gotestfmt-$$ artifacts: diff --git a/.gotestfmt/package.gotpl b/.gotestfmt/package.gotpl index 83c254b..1675d5b 100644 --- a/.gotestfmt/package.gotpl +++ b/.gotestfmt/package.gotpl @@ -38,7 +38,6 @@ This template contains the format for an individual package. {{- "\n" -}} {{- end -}} - {{- "\n" -}} {{- end -}} {{- end -}} {{- "\n" -}} \ No newline at end of file diff --git a/README.md b/README.md index 807998b..778f365 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,15 @@ Then this is the tool for you. Run it locally, or in any CI system with the foll ```bash set -euo pipefail -go test -v ./... 2>&1 | tee /tmp/gotest.log | gotestfmt +go test -json -v ./... 2>&1 | tee /tmp/gotest.log | gotestfmt ``` Tadam, your tests will now show up in a beautifully formatted fashion. Plug it into your CI, and you're done. **Note:** Please always save the original log. You will need it if you have to file a bug report for gotestfmt. +**⚠️ With version 2.0 gotestfmt switched to supporting only JSON output. Please add the `-json` flag to your `go test` command line!** + ## Setting it up in your CI system We have support for several CI systems, and you can also customize the output to match your system. Gotestfmt detects the CI system based on environment variables. If it can't detect the CI system it will try to create a generic colored test output. You can force the CI output with the `-ci github|gitlab|...` option. @@ -55,7 +57,7 @@ jobs: - name: Run tests run: | set -euo pipefail - go test -v ./... 2>&1 | tee /tmp/gotest.log | gotestfmt + go test -json -v ./... 2>&1 | tee /tmp/gotest.log | gotestfmt # Upload the original go test log as an artifact for later review. - name: Upload test log @@ -88,7 +90,7 @@ COPY --from gotestfmt /gotestfmt /usr/local/bin/ You can then run the tests within this image with the following command: ```bash -go test -v ./... | /usr/local/bin/gotestfmt +go test -json -v ./... | /usr/local/bin/gotestfmt ``` To put it all together, you can use the following `.gitlab-ci.yaml`: @@ -109,7 +111,7 @@ docker-build: -v /tmp:/tmp | -e GITLAB_CI=${GITLAB_CI} \ gotestfmt \ - /bin/sh -c "cd /source; go test -v ./... 2>&1 | tee /tmp/gotest.log | /usr/local/bin/gotestfmt" + /bin/sh -c "cd /source; go test -json -v ./... 2>&1 | tee /tmp/gotest.log | /usr/local/bin/gotestfmt" artifacts: paths: - /tmp/gotest.log @@ -140,7 +142,7 @@ jobs: version: 19.03.13 - run: name: Run tests - command: go test -v ./... 2>&1 | tee /tmp/gotest.log | docker run -i ghcr.io/haveyoudebuggedit/gotestfmt:latest + command: go test -json -v ./... 2>&1 | tee /tmp/gotest.log | docker run -i ghcr.io/haveyoudebuggedit/gotestfmt:latest - store_artifacts: path: /tmp/gotest.log destination: gotest.log diff --git a/_testsource/coverage/code.go b/_testsource/coverage/code.go new file mode 100644 index 0000000..33bca98 --- /dev/null +++ b/_testsource/coverage/code.go @@ -0,0 +1,5 @@ +package example + +func Hello() string { + return "Hello world!" +} diff --git a/_testsource/coverage/code_test.go b/_testsource/coverage/code_test.go new file mode 100644 index 0000000..d3c1de4 --- /dev/null +++ b/_testsource/coverage/code_test.go @@ -0,0 +1,13 @@ +package example_test + +import ( + "testing" + + "github.com/haveyoudebuggedit/example" +) + +func TestHello(t *testing.T) { + if example.Hello() != "Hello world!" { + t.Fail() + } +} diff --git a/_testsource/coverage/go.mod b/_testsource/coverage/go.mod new file mode 100644 index 0000000..26f2703 --- /dev/null +++ b/_testsource/coverage/go.mod @@ -0,0 +1,4 @@ +module github.com/haveyoudebuggedit/example + +go 1.16 + diff --git a/cmd/gotestfmt/main.go b/cmd/gotestfmt/main.go index 12ea18a..ee386ab 100644 --- a/cmd/gotestfmt/main.go +++ b/cmd/gotestfmt/main.go @@ -30,12 +30,19 @@ func main() { "./.gotestfmt", } ci := "" + inputFile := "-" flag.StringVar( &ci, "ci", ci, "Which subdirectory to use within the .gotestfmt folder. Defaults to detecting the CI from environment variables.", ) + flag.StringVar( + &inputFile, + "input", + inputFile, + "Read build log from file. Defaults to standard input.", + ) flag.Parse() if ci != "" { @@ -57,5 +64,18 @@ func main() { if err != nil { panic(err) } - format.Format(os.Stdin, os.Stdout) + + input := os.Stdin + if inputFile != "-" { + fh, err := os.Open(inputFile) + if err != nil { + panic(err) + } + defer func() { + _ = fh.Close() + }() + input = fh + } + + format.Format(input, os.Stdout) } diff --git a/parser/model.go b/parser/model.go index 4678969..b9ba216 100644 --- a/parser/model.go +++ b/parser/model.go @@ -29,6 +29,8 @@ type TestCase struct { Coverage *float64 // Output is the log output of this test case. Output string + // Cached indicates that the test results are cached and the tests have not actually been run. + Cached bool } // ID returns the Name of the test case without slashes @@ -62,8 +64,12 @@ type Package struct { Output string // TestCases is a list of test cases run in this package. Subtests are included as separate test cases. TestCases []*TestCase + // TestCasesByName holds the test cases mapped by name. + TestCasesByName map[string]*TestCase // Reason is a description of why the Result happened. Empty in most cases. Reason string + // Cached indicates that the results came from the go test cache. + Cached bool } func (p *Package) EndTime() *time.Time { @@ -95,7 +101,7 @@ type Download struct { // Downloads is the context for TemplatePackageDownloads. type Downloads struct { - // Packages is a list of packages + // Packages is a list of packagesByName Packages []*Download `json:"packages"` // Failed indicates that one or more package downloads failed. Failed bool `json:"failed"` @@ -105,7 +111,7 @@ type Downloads struct { EndTime *time.Time `json:"-"` } -// ParseResult is an overall structure for parser results, containing the prefix text, downloads and packages. +// ParseResult is an overall structure for parser results, containing the prefix text, downloads and packagesByName. type ParseResult struct { Prefix []string `json:"prefix"` Downloads Downloads `json:"downloads"` diff --git a/parser/parse.go b/parser/parse.go index 0250213..c87555b 100644 --- a/parser/parse.go +++ b/parser/parse.go @@ -2,7 +2,10 @@ package parser import ( "fmt" + "math" "regexp" + "sort" + "strings" "time" "github.com/haveyoudebuggedit/gotestfmt/tokenizer" @@ -23,7 +26,9 @@ func Parse( return prefixChannel, downloadsChannel, packagesChannel } -var noModuleProvidesRegexp = regexp.MustCompile(`no required module provides package (?P[^\s]+);`) +var downloadErrors = []*regexp.Regexp{ + regexp.MustCompile(`no required module provides package (?P[^\s]+);`), +} func parse( evts <-chan tokenizer.Event, @@ -31,6 +36,7 @@ func parse( downloadsChannel chan *Downloads, packagesChannel chan *Package, ) { + outputStarted := false downloadTracker := &downloadsTracker{ prefixChannel: prefixChannel, downloadResultsList: nil, @@ -39,13 +45,8 @@ func parse( target: downloadsChannel, } pkgTracker := &packageTracker{ - currentPackage: nil, - packageList: []*Package{}, - packages: map[string]*Package{}, - testCases: nil, - lastTestCase: nil, - testCasesByName: map[string]*TestCase{}, - target: packagesChannel, + packagesByName: map[string]*Package{}, + target: packagesChannel, } defer func() { @@ -54,278 +55,286 @@ func parse( close(packagesChannel) }() - var lastAction tokenizer.Action + var prevErroredDownload string + var prevErroredPkg string for { evt, ok := <-evts if !ok { return } - if evt.Action != tokenizer.ActionDownload && - evt.Action != tokenizer.ActionDownloadFailed && - evt.Action != tokenizer.ActionStdout { - downloadTracker.Write() - if evt.Package != "" { - pkgTracker.SetPackage( - &Package{ - Name: evt.Package, - }, - ) + if evt.Action != tokenizer.ActionStdout { + outputStarted = true + } + if evt.Action != tokenizer.ActionDownload && evt.Action != tokenizer.ActionDownloadFailed && evt.Package != "" { + pkgTracker.SetTestStartTime(evt.Package, evt.Test, evt.Received) + if evt.Elapsed != 0 { + pkgTracker.SetTestElapsed(evt.Package, evt.Test, evt.Elapsed) + } + if evt.Coverage != nil { + pkgTracker.SetCoverage(evt.Package, evt.Test, *evt.Coverage) + } + if evt.Cached { + pkgTracker.SetCached(evt.Package, evt.Test) } } - prevaction: + switch evt.Action { - case tokenizer.ActionRun: - fallthrough - case tokenizer.ActionCont: - pkgTracker.SetLastTest(evt.Test) + case tokenizer.ActionFailFinal: + pkgTracker.SetResult(evt.Package, evt.Test, ResultFail) + if len(evt.Output) > 0 { + pkgTracker.AddReason(evt.Package, string(evt.Output)) + } + case tokenizer.ActionSkipFinal: + pkgTracker.SetResult(evt.Package, evt.Test, ResultSkip) + if len(evt.Output) > 0 { + pkgTracker.AddReason(evt.Package, string(evt.Output)) + } + case tokenizer.ActionPassFinal: + pkgTracker.SetResult(evt.Package, evt.Test, ResultPass) + if len(evt.Output) > 0 { + pkgTracker.AddReason(evt.Package, string(evt.Output)) + } case tokenizer.ActionFail: - result := ResultFail - finish(evt, pkgTracker, result) + pkgTracker.SetResult(evt.Package, evt.Test, ResultFail) + if len(evt.Output) > 0 { + pkgTracker.AddReason(evt.Package, string(evt.Output)) + } case tokenizer.ActionPass: - result := ResultPass - finish(evt, pkgTracker, result) + pkgTracker.SetResult(evt.Package, evt.Test, ResultPass) + if len(evt.Output) > 0 { + pkgTracker.AddReason(evt.Package, string(evt.Output)) + } case tokenizer.ActionSkip: - result := ResultSkip - finish(evt, pkgTracker, result) + pkgTracker.SetResult(evt.Package, evt.Test, ResultSkip) + if len(evt.Output) > 0 { + pkgTracker.AddReason(evt.Package, string(evt.Output)) + } case tokenizer.ActionDownload: downloadTracker.Add( - &Download{ - Package: evt.Package, - Version: evt.Version, - }, + evt.Package, + evt.Version, ) case tokenizer.ActionDownloadFailed: - downloadTracker.Add( - &Download{ - Package: evt.Package, - Version: evt.Version, - Failed: true, - Reason: string(evt.Output), - }, - ) + prevErroredDownload = evt.Package + downloadTracker.SetDownloadFailed(evt.Package, evt.Version) + downloadTracker.AddReason(evt.Package, evt.Output) case tokenizer.ActionPackage: - pkgTracker.SetPackage( - &Package{ - Name: evt.Package, - }, - ) + pkgTracker.SetResult(evt.Package, "", ResultFail) + prevErroredPkg = evt.Package case tokenizer.ActionStdout: - switch lastAction { - case "": - // Special case: error message right before any output indicates that there was an error downloading a - // dependency. We will try to identify it here. - pkg := "" - if match := noModuleProvidesRegexp.FindSubmatch(evt.Output); len(match) != 0 { - pkg = string(match[1]) - } else { - prefixChannel <- string(evt.Output) - break prevaction - } - evt.Action = tokenizer.ActionDownloadFailed - downloadTracker.Add( - &Download{ - Package: pkg, - }, - ) - fallthrough - case tokenizer.ActionDownloadFailed: - fallthrough - case tokenizer.ActionDownload: - lastDownload := downloadTracker.GetLast() - lastDownload.Failed = true - if lastDownload.Reason == "" { - lastDownload.Reason = string(evt.Output) - } else { - lastDownload.Reason = fmt.Sprintf( - "%s\n%s", - lastDownload.Reason, - string(evt.Output), - ) + if evt.JSON { + // We have a JSON-encoded output, that makes things much easier. + pkgTracker.AddOutput(evt.Package, evt.Test, evt.Output) + } else if len(evt.Output) > 0 { + // We don't have a JSON output, so this must be an error. + foundDLError := false + for _, dlError := range downloadErrors { + if submatch := dlError.FindSubmatch(evt.Output); len(submatch) > 0 { + pkgName := string(submatch[1]) + downloadTracker.SetDownloadFailed(pkgName, "") + downloadTracker.AddReason(pkgName, evt.Output) + prevErroredDownload = pkgName + foundDLError = true + outputStarted = true + } } - case tokenizer.ActionRun: - fallthrough - case tokenizer.ActionPass: - fallthrough - case tokenizer.ActionFail: - fallthrough - case tokenizer.ActionSkip: - fallthrough - case tokenizer.ActionCont: - lastTestCase := pkgTracker.GetLastTestCase() - if lastTestCase != nil && len(evt.Output) > 0 { - if lastTestCase.Output == "" { - lastTestCase.Output = string(evt.Output) + if !foundDLError { + if prevErroredDownload != "" { + downloadTracker.AddReason(prevErroredDownload, evt.Output) + } else if prevErroredPkg != "" { + pkgTracker.AddOutput(prevErroredPkg, "", evt.Output) + } else if !outputStarted { + prefixChannel <- string(evt.Output) } else { - lastTestCase.Output = fmt.Sprintf( - "%s\n%s", - lastTestCase.Output, - string(evt.Output), + panic( + fmt.Errorf( + "unexpected output encountered: %s (Did you use -json on go test?)", + evt.Output, + ), ) } } - case tokenizer.ActionPackage: - lastPackage := pkgTracker.GetPackage() - if lastPackage.Output == "" { - lastPackage.Output = string(evt.Output) - } else { - lastPackage.Output = fmt.Sprintf( - "%s\n%s", - lastPackage.Output, - string(evt.Output), - ) - } - case tokenizer.ActionFailFinal: - fallthrough - case tokenizer.ActionPassFinal: - fallthrough - case tokenizer.ActionSkipFinal: - pkgTracker.Write() - default: - if len(evt.Output) > 0 { - panic(fmt.Errorf("unexpected output after %s event: %s", lastAction, evt.Output)) - } } } - if evt.Action != tokenizer.ActionStdout { - lastAction = evt.Action + if evt.Action != tokenizer.ActionStdout && + evt.Action != tokenizer.ActionDownloadFailed && + evt.Action != tokenizer.ActionPackage { + prevErroredDownload = "" + prevErroredPkg = "" } } } -func finish(evt tokenizer.Event, pkgTracker *packageTracker, result Result) { - if evt.Test != "" { - pkgTracker.SetLastTest(evt.Test) - lastTestCase := pkgTracker.GetLastTestCase() - lastTestCase.Result = result - lastTestCase.Duration = evt.Elapsed - lastTestCase.Coverage = evt.Coverage - } - if evt.Package != "" { - pkgTracker.SetPackage( - &Package{ - Name: evt.Package, - Result: result, - Duration: evt.Elapsed, - Reason: string(evt.Output), - Coverage: evt.Coverage, - }, - ) - pkgTracker.currentPackage = nil - } +type packageTracker struct { + packages []*Package + packagesByName map[string]*Package + target chan<- *Package } -type packageTracker struct { - currentPackage *Package - packages map[string]*Package - testCases []*TestCase - lastTestCase *TestCase - testCasesByName map[string]*TestCase - target chan<- *Package - packageList []*Package +func (p *packageTracker) AddOutput(pkg string, test string, output []byte) { + pkgObj := p.ensurePackage(pkg) + if test == "" { + pkgObj.Output = pkgObj.Output + string(output) + "\n" + return + } + testCase := p.ensureTest(pkgObj, test) + testCase.Output = testCase.Output + string(output) + "\n" } -func (p *packageTracker) SetPackage(pkg *Package) { - if p.currentPackage == nil { - pkg.TestCases = p.testCases - p.currentPackage = pkg - if _, ok := p.packages[pkg.Name]; !ok { - p.packageList = append(p.packageList, pkg) - p.packages[pkg.Name] = pkg +func (p *packageTracker) ensureTest(pkgObj *Package, test string) *TestCase { + if _, ok := pkgObj.TestCasesByName[test]; !ok { + tc := &TestCase{ + StartTime: nil, + Name: test, + Result: "", + Duration: 0, + Coverage: nil, + Output: "", } - - p.testCases = nil - return - } else if p.currentPackage.Name != pkg.Name { - p.currentPackage = p.packages[pkg.Name] + pkgObj.TestCasesByName[test] = tc + pkgObj.TestCases = append(pkgObj.TestCases, tc) } - if pkg.Result != "" { - p.currentPackage.Result = pkg.Result + return pkgObj.TestCasesByName[test] +} + +func (p *packageTracker) ensurePackage(pkg string) *Package { + if pkg == "" { + panic("BUG: Empty package name encountered.") } - if pkg.Coverage != nil { - p.currentPackage.Coverage = pkg.Coverage + if _, ok := p.packagesByName[pkg]; !ok { + pkgObj := &Package{ + StartTime: nil, + Name: pkg, + Result: "", + Duration: 0, + Coverage: nil, + Output: "", + TestCases: nil, + TestCasesByName: map[string]*TestCase{}, + Reason: "", + } + p.packagesByName[pkg] = pkgObj + p.packages = append(p.packages, pkgObj) } - if len(pkg.TestCases) != 0 { - p.currentPackage.TestCases = pkg.TestCases + return p.packagesByName[pkg] +} + +func (p *packageTracker) SetTestStartTime(pkg string, test string, startTime time.Time) { + if pkg == "" { + return } - if len(pkg.Output) != 0 { - p.currentPackage.Output = pkg.Output + pkgObj := p.ensurePackage(pkg) + if test == "" { + if pkgObj.StartTime == nil { + pkgObj.StartTime = &startTime + } + return } - if len(pkg.Reason) != 0 { - p.currentPackage.Reason = pkg.Reason + testCase := p.ensureTest(pkgObj, test) + if testCase.StartTime == nil { + testCase.StartTime = &startTime } - if pkg.Duration != 0 { - p.currentPackage.Duration = pkg.Duration +} + +func (p *packageTracker) SetTestElapsed(pkg string, test string, elapsed time.Duration) { + if pkg == "" { + return } - if pkg.StartTime != nil { - p.currentPackage.StartTime = pkg.StartTime - } else if p.currentPackage != nil { - t := time.Now() - p.currentPackage.StartTime = &t + pkgObj := p.ensurePackage(pkg) + if test == "" { + pkgObj.Duration = elapsed + return } + testCase := p.ensureTest(pkgObj, test) + testCase.Duration = elapsed } -func (p *packageTracker) Add(testCase *TestCase) { - if testCase.StartTime == nil { - t := time.Now() - testCase.StartTime = &t +func (p *packageTracker) SetResult(pkg string, test string, result Result) { + if pkg == "" { + return } - p.lastTestCase = testCase - p.testCasesByName[testCase.Name] = testCase - if p.currentPackage != nil { - p.currentPackage.TestCases = append(p.currentPackage.TestCases, testCase) - } else { - p.testCases = append(p.testCases, testCase) + pkgObj := p.ensurePackage(pkg) + if test == "" { + pkgObj.Result = result + return } + testCase := p.ensureTest(pkgObj, test) + testCase.Result = result } -func (p *packageTracker) GetLastTestCase() *TestCase { - return p.lastTestCase +func (p *packageTracker) SetCoverage(pkg string, test string, coverage float64) { + if pkg == "" { + return + } + pkgObj := p.ensurePackage(pkg) + if test == "" { + pkgObj.Coverage = &coverage + return + } + testCase := p.ensureTest(pkgObj, test) + testCase.Coverage = &coverage } -func (p *packageTracker) Write() { - if p.currentPackage == nil { - if len(p.testCases) > 0 { - startTime := time.Now() - for _, testCase := range p.testCases { - if testCase.StartTime != nil && testCase.StartTime.Before(startTime) { - startTime = *testCase.StartTime - } - } - p.target <- &Package{ - TestCases: p.testCases, - StartTime: &startTime, - } - } - p.testCases = nil - } - for _, pkg := range p.packageList { - p.target <- pkg +func (p *packageTracker) AddReason(pkg string, reason string) { + if pkg == "" { + return } - p.packages = map[string]*Package{} - p.packageList = []*Package{} - p.currentPackage = nil - p.testCasesByName = map[string]*TestCase{} + pkgObj := p.ensurePackage(pkg) + pkgObj.Reason = pkgObj.Reason + reason + "\n" } -func (p *packageTracker) GetTestCase(test string) *TestCase { - return p.testCasesByName[test] +func (p *packageTracker) SetCached(pkg string, test string) { + if pkg == "" { + return + } + pkgObj := p.ensurePackage(pkg) + if test == "" { + pkgObj.Cached = true + return + } + testCase := p.ensureTest(pkgObj, test) + testCase.Cached = true } -func (p *packageTracker) SetLastTest(test string) { - if _, ok := p.testCasesByName[test]; !ok { - p.Add( - &TestCase{ - Name: test, +func (p *packageTracker) Write() { + sort.SliceStable( + p.packages, func(i, j int) bool { + return p.packages[i].Name < p.packages[j].Name + }, + ) + for _, pkg := range p.packages { + pkg.Output = strings.TrimRight(pkg.Output, "\n") + pkg.Reason = strings.TrimRight(pkg.Reason, "\n") + sort.SliceStable( + pkg.TestCases, func(i, j int) bool { + return compareTestCaseNames(pkg.TestCases[i].Name, pkg.TestCases[j].Name) }, ) + for _, tc := range pkg.TestCases { + tc.Output = strings.TrimRight(tc.Output, "\n") + } + } + for _, pkg := range p.packages { + p.target <- pkg } - p.lastTestCase = p.testCasesByName[test] } -func (p *packageTracker) GetPackage() *Package { - return p.currentPackage +func compareTestCaseNames(name1 string, name2 string) bool { + parts1 := strings.SplitN(name1, "/", -1) + parts2 := strings.SplitN(name2, "/", -1) + + for i := 0; i < int(math.Min(float64(len(parts1)), float64(len(parts2)))); i++ { + part1 := parts1[i] + part2 := parts2[i] + if part1 < part2 { + return true + } else if part1 > part2 { + return false + } + } + return len(parts1) < len(parts2) } type downloadsTracker struct { @@ -339,22 +348,16 @@ type downloadsTracker struct { endTime *time.Time } -func (d *downloadsTracker) Add(download *Download) { +func (d *downloadsTracker) Add(name string, version string) { if d.downloadsFinished { - panic(fmt.Errorf("tried to add download after downloads are already finished (%v)", download)) + panic(fmt.Errorf("tried to add download after downloads are already finished (%v)", name)) } - t := time.Now() - if d.startTime == nil { - d.startTime = &t - } - d.endTime = &t - packageID := fmt.Sprintf("%s@%s", download.Package, download.Version) - if _, ok := d.downloadsByPackage[packageID]; ok { - panic(fmt.Errorf("download already exists in tracker (%v)", download)) + + pkg := d.ensurePackage(name) + if version != "" { + pkg.Version = version } - d.downloadsByPackage[packageID] = download - d.downloadResultsList = append(d.downloadResultsList, download) - d.lastDownload = download + d.lastDownload = pkg } func (d *downloadsTracker) GetLast() *Download { @@ -370,8 +373,8 @@ func (d *downloadsTracker) Write() { for _, dl := range d.downloadResultsList { if dl.Failed { failed = true - break } + dl.Reason = strings.TrimRight(dl.Reason, "\n") } d.target <- &Downloads{ Packages: d.downloadResultsList, @@ -384,3 +387,37 @@ func (d *downloadsTracker) Write() { d.downloadsByPackage = nil close(d.target) } + +func (d *downloadsTracker) SetDownloadFailed(name string, version string) { + if d.downloadsFinished { + panic(fmt.Errorf("tried to add download after downloads are already finished (%v)", name)) + } + pkg := d.ensurePackage(name) + if version != "" { + pkg.Version = version + } + pkg.Failed = true +} + +func (d *downloadsTracker) ensurePackage(name string) *Download { + t := time.Now() + if d.startTime == nil { + d.startTime = &t + } + d.endTime = &t + if _, ok := d.downloadsByPackage[name]; !ok { + d.downloadsByPackage[name] = &Download{ + Package: name, + } + d.downloadResultsList = append(d.downloadResultsList, d.downloadsByPackage[name]) + } + return d.downloadsByPackage[name] +} + +func (d *downloadsTracker) AddReason(name string, output []byte) { + if d.downloadsFinished { + panic(fmt.Errorf("tried to add download after downloads are already finished (%v)", name)) + } + pkg := d.ensurePackage(name) + pkg.Reason = pkg.Reason + string(output) + "\n" +} diff --git a/testdata/coverage-nostatements.parser.json b/testdata/coverage-nostatements.parser.json index 5ecd16c..bb1ff5a 100644 --- a/testdata/coverage-nostatements.parser.json +++ b/testdata/coverage-nostatements.parser.json @@ -6,7 +6,7 @@ { "name": "github.com/haveyoudebuggedit/example", "result": "PASS", - "duration": "0.024s", + "duration": "0.101s", "testcases": [ { "name": "TestNothing", diff --git a/testdata/coverage-nostatements.tokenizer.json b/testdata/coverage-nostatements.tokenizer.json index 88a8db4..1d3f043 100644 --- a/testdata/coverage-nostatements.tokenizer.json +++ b/testdata/coverage-nostatements.tokenizer.json @@ -1,21 +1,30 @@ [ { "action": "run", - "test": "TestNothing" + "test": "TestNothing", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "pass", - "test": "TestNothing" + "test": "TestNothing", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { - "action": "pass-final" + "action": "pass-final", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { - "action": "coverage_nostatements" + "action": "coverage_nostatements", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "pass", "package": "github.com/haveyoudebuggedit/example", - "elapsed": "0.024s" + "elapsed": "0.101s", + "json": true } ] \ No newline at end of file diff --git a/testdata/coverage-nostatements.txt b/testdata/coverage-nostatements.txt index bfe7fd3..abd3922 100644 --- a/testdata/coverage-nostatements.txt +++ b/testdata/coverage-nostatements.txt @@ -1,5 +1,8 @@ -=== RUN TestNothing ---- PASS: TestNothing (0.00s) -PASS -coverage: [no statements] -ok github.com/haveyoudebuggedit/example 0.024s coverage: [no statements] \ No newline at end of file +{"Time":"2021-12-05T06:52:51.0659309+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing"} +{"Time":"2021-12-05T06:52:51.0664674+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing","Output":"=== RUN TestNothing\n"} +{"Time":"2021-12-05T06:52:51.0670068+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing","Output":"--- PASS: TestNothing (0.00s)\n"} +{"Time":"2021-12-05T06:52:51.0670068+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing","Elapsed":0} +{"Time":"2021-12-05T06:52:51.0675327+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"PASS\n"} +{"Time":"2021-12-05T06:52:51.0675327+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"coverage: [no statements]\n"} +{"Time":"2021-12-05T06:52:51.0726828+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"ok \tgithub.com/haveyoudebuggedit/example\t0.101s\tcoverage: [no statements]\n"} +{"Time":"2021-12-05T06:52:51.0810939+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Elapsed":0.11} \ No newline at end of file diff --git a/testdata/coverage.parser.json b/testdata/coverage.parser.json index e5b36f4..ed8178e 100644 --- a/testdata/coverage.parser.json +++ b/testdata/coverage.parser.json @@ -6,10 +6,11 @@ { "name": "github.com/haveyoudebuggedit/example", "result": "PASS", - "coverage": 57.8, + "duration": "102ms", + "coverage": 100, "testcases": [ { - "name": "TestNothing", + "name": "TestHello", "result": "PASS" } ] diff --git a/testdata/coverage.tokenizer.json b/testdata/coverage.tokenizer.json index 7c08637..4b3f61b 100644 --- a/testdata/coverage.tokenizer.json +++ b/testdata/coverage.tokenizer.json @@ -1,23 +1,38 @@ [ { "action": "run", - "test": "TestNothing" + "test": "TestHello", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "pass", - "test": "TestNothing" + "test": "TestHello", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { - "action": "pass-final" + "action": "pass-final", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "coverage", - "coverage": 57.8 + "package": "github.com/haveyoudebuggedit/example", + "json": true, + "version": "", + "test": "", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": 100 }, { "action": "pass", "package": "github.com/haveyoudebuggedit/example", - "cached": true, - "coverage": 57.8 + "json": true, + "cached": false, + "elapsed": "102ms", + "coverage": 100 } ] \ No newline at end of file diff --git a/testdata/coverage.txt b/testdata/coverage.txt index 8a0a496..f289da0 100644 --- a/testdata/coverage.txt +++ b/testdata/coverage.txt @@ -1,5 +1,8 @@ -=== RUN TestNothing ---- PASS: TestNothing (0.00s) -PASS -coverage: 57.8% of statements -ok github.com/haveyoudebuggedit/example (cached) coverage: 57.8% of statements \ No newline at end of file +{"Time":"2021-12-05T07:39:07.2048256+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestHello"} +{"Time":"2021-12-05T07:39:07.2058673+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestHello","Output":"=== RUN TestHello\n"} +{"Time":"2021-12-05T07:39:07.2058673+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestHello","Output":"--- PASS: TestHello (0.00s)\n"} +{"Time":"2021-12-05T07:39:07.2068666+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Test":"TestHello","Elapsed":0} +{"Time":"2021-12-05T07:39:07.2068666+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"PASS\n"} +{"Time":"2021-12-05T07:39:07.2068666+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"coverage: 100.0% of statements\n"} +{"Time":"2021-12-05T07:39:07.211866+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"ok \tgithub.com/haveyoudebuggedit/example\t0.102s\tcoverage: 100.0% of statements\n"} +{"Time":"2021-12-05T07:39:07.2218653+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Elapsed":0.112} \ No newline at end of file diff --git a/testdata/gotestfmt.parser.json b/testdata/gotestfmt.parser.json deleted file mode 100644 index 4a3765a..0000000 --- a/testdata/gotestfmt.parser.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "prefix": null, - "downloads": { - "packages": null, - "failed": false - }, - "packages": [ - { - "name": "github.com/haveyoudebuggedit/gotestfmt", - "result": "SKIP", - "duration": "0s", - "coverage": null, - "output": "", - "testcases": null, - "reason": "no test files" - }, - { - "name": "github.com/haveyoudebuggedit/gotestfmt/cmd/gotestfmt", - "result": "SKIP", - "duration": "0s", - "coverage": null, - "output": "", - "testcases": null, - "reason": "no test files" - }, - { - "name": "github.com/haveyoudebuggedit/gotestfmt/parser", - "result": "PASS", - "duration": "0s", - "coverage": null, - "output": "", - "testcases": null, - "reason": "" - }, - { - "name": "github.com/haveyoudebuggedit/gotestfmt/renderer", - "result": "SKIP", - "duration": "0s", - "coverage": null, - "output": "", - "testcases": null, - "reason": "no test files" - }, - { - "name": "github.com/haveyoudebuggedit/gotestfmt/testutil", - "result": "SKIP", - "duration": "0s", - "coverage": null, - "output": "", - "testcases": null, - "reason": "no test files" - }, - { - "name": "github.com/haveyoudebuggedit/gotestfmt/tokenizer", - "result": "PASS", - "duration": "0s", - "coverage": null, - "output": "", - "testcases": null, - "reason": "" - } - ] -} \ No newline at end of file diff --git a/testdata/gotestfmt.tokenizer.json b/testdata/gotestfmt.tokenizer.json deleted file mode 100644 index d6c248c..0000000 --- a/testdata/gotestfmt.tokenizer.json +++ /dev/null @@ -1,72 +0,0 @@ -[ - { - "action": "skip", - "package": "github.com/haveyoudebuggedit/gotestfmt", - "version": "", - "test": "", - "elapsed": "0s", - "output": "bm8gdGVzdCBmaWxlcw==", - "cached": false, - "coverage": null - }, - { - "action": "skip", - "package": "github.com/haveyoudebuggedit/gotestfmt/cmd/gotestfmt", - "version": "", - "test": "", - "elapsed": "0s", - "output": "bm8gdGVzdCBmaWxlcw==", - "cached": false, - "coverage": null - }, - { - "action": "pass", - "package": "github.com/haveyoudebuggedit/gotestfmt/parser", - "version": "", - "test": "", - "elapsed": "0s", - "output": null, - "cached": true, - "coverage": null - }, - { - "action": "skip", - "package": "github.com/haveyoudebuggedit/gotestfmt/renderer", - "version": "", - "test": "", - "elapsed": "0s", - "output": "bm8gdGVzdCBmaWxlcw==", - "cached": false, - "coverage": null - }, - { - "action": "skip", - "package": "github.com/haveyoudebuggedit/gotestfmt/testutil", - "version": "", - "test": "", - "elapsed": "0s", - "output": "bm8gdGVzdCBmaWxlcw==", - "cached": false, - "coverage": null - }, - { - "action": "pass", - "package": "github.com/haveyoudebuggedit/gotestfmt/tokenizer", - "version": "", - "test": "", - "elapsed": "0s", - "output": null, - "cached": true, - "coverage": null - }, - { - "action": "stdout", - "package": "", - "version": "", - "test": "", - "elapsed": "0s", - "output": "", - "cached": false, - "coverage": null - } -] \ No newline at end of file diff --git a/testdata/gotestfmt.txt b/testdata/gotestfmt.txt deleted file mode 100644 index 9dbe69c..0000000 --- a/testdata/gotestfmt.txt +++ /dev/null @@ -1,6 +0,0 @@ -? github.com/haveyoudebuggedit/gotestfmt [no test files] -? github.com/haveyoudebuggedit/gotestfmt/cmd/gotestfmt [no test files] -ok github.com/haveyoudebuggedit/gotestfmt/parser (cached) -? github.com/haveyoudebuggedit/gotestfmt/renderer [no test files] -? github.com/haveyoudebuggedit/gotestfmt/testutil [no test files] -ok github.com/haveyoudebuggedit/gotestfmt/tokenizer (cached) diff --git a/testdata/misattribution.parser.json b/testdata/misattribution.parser.json deleted file mode 100644 index 379a10a..0000000 --- a/testdata/misattribution.parser.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "prefix": null, - "downloads": { - "packages": null, - "failed": false - }, - "packages": [ - { - "name": "github.com/haveyoudebuggedit/gotestfmt/renderer", - "result": "SKIP", - "duration": "0s", - "coverage": null, - "output": "", - "testcases": null, - "reason": "no test files" - }, - { - "name": "github.com/haveyoudebuggedit/gotestfmt/testutil", - "result": "PASS", - "duration": "5.003s", - "coverage": null, - "output": "", - "testcases": [ - { - "name": "TestSleep", - "result": "PASS", - "duration": "5s", - "coverage": null, - "output": " sleep_test.go:10: Now sleeping for 5 seconds...\n sleep_test.go:12: Welcome back, now finishing test." - } - ], - "reason": "" - } - ] -} \ No newline at end of file diff --git a/testdata/misattribution.txt b/testdata/misattribution.txt deleted file mode 100644 index e109b3a..0000000 --- a/testdata/misattribution.txt +++ /dev/null @@ -1,7 +0,0 @@ -? github.com/haveyoudebuggedit/gotestfmt/renderer [no test files] -=== RUN TestSleep - sleep_test.go:10: Now sleeping for 5 seconds... - sleep_test.go:12: Welcome back, now finishing test. ---- PASS: TestSleep (5.00s) -PASS -ok github.com/haveyoudebuggedit/gotestfmt/testutil 5.003s \ No newline at end of file diff --git a/testdata/mod-download.parser.json b/testdata/mod-download.parser.json index 08967ed..ec25234 100644 --- a/testdata/mod-download.parser.json +++ b/testdata/mod-download.parser.json @@ -24,7 +24,7 @@ { "name": "github.com/haveyoudebuggedit/example", "result": "PASS", - "duration": "0.027s", + "duration": "0.105s", "testcases": [ { "name": "TestNothing", diff --git a/testdata/mod-download.tokenizer.json b/testdata/mod-download.tokenizer.json index 8a472bb..b36a66f 100644 --- a/testdata/mod-download.tokenizer.json +++ b/testdata/mod-download.tokenizer.json @@ -21,18 +21,25 @@ }, { "action": "run", - "test": "TestNothing" + "test": "TestNothing", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "pass", - "test": "TestNothing" + "test": "TestNothing", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { - "action": "pass-final" + "action": "pass-final", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "pass", "package": "github.com/haveyoudebuggedit/example", - "elapsed": "0.027s" + "elapsed": "0.105s", + "json": true } ] \ No newline at end of file diff --git a/testdata/mod-download.txt b/testdata/mod-download.txt index db52384..4120eba 100644 --- a/testdata/mod-download.txt +++ b/testdata/mod-download.txt @@ -2,7 +2,10 @@ go: downloading github.com/stretchr/testify v1.7.0 go: downloading github.com/pmezard/go-difflib v1.0.0 go: downloading github.com/davecgh/go-spew v1.1.0 go: downloading gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c -=== RUN TestNothing ---- PASS: TestNothing (0.00s) -PASS -ok github.com/haveyoudebuggedit/example 0.027s \ No newline at end of file +{"Time":"2021-12-05T06:51:55.2932632+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing"} +{"Time":"2021-12-05T06:51:55.2943439+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing","Output":"=== RUN TestNothing\n"} +{"Time":"2021-12-05T06:51:55.2948686+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing","Output":"--- PASS: TestNothing (0.00s)\n"} +{"Time":"2021-12-05T06:51:55.29541+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Test":"TestNothing","Elapsed":0} +{"Time":"2021-12-05T06:51:55.29541+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"PASS\n"} +{"Time":"2021-12-05T06:51:55.2999702+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"ok \tgithub.com/haveyoudebuggedit/example\t0.105s\n"} +{"Time":"2021-12-05T06:51:55.3109276+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Elapsed":0.116} \ No newline at end of file diff --git a/testdata/multipackage-syntax-json.parser.json b/testdata/multipackage-syntax-json.parser.json new file mode 100644 index 0000000..ecc8d38 --- /dev/null +++ b/testdata/multipackage-syntax-json.parser.json @@ -0,0 +1,32 @@ +{ + "downloads": { + "failed": false + }, + "packages": [ + { + "name": "github.com/haveyoudebuggedit/example", + "result": "FAIL", + "duration": "0s", + "coverage": null, + "output": "nothing_test.go:7:11: expected '(', found Nothing", + "reason": "setup failed" + }, + { + "name": "github.com/haveyoudebuggedit/example/second", + "result": "PASS", + "duration": "2ms", + "coverage": null, + "output": "", + "testcases": [ + { + "name": "TestNothing", + "result": "PASS", + "duration": "0s", + "coverage": null, + "output": "" + } + ], + "reason": "" + } + ] +} \ No newline at end of file diff --git a/testdata/misattribution.tokenizer.json b/testdata/multipackage-syntax-json.tokenizer.json similarity index 50% rename from testdata/misattribution.tokenizer.json rename to testdata/multipackage-syntax-json.tokenizer.json index 0215c90..58dad42 100644 --- a/testdata/misattribution.tokenizer.json +++ b/testdata/multipackage-syntax-json.tokenizer.json @@ -1,72 +1,76 @@ [ { - "action": "skip", - "package": "github.com/haveyoudebuggedit/gotestfmt/renderer", + "action": "package", + "package": "github.com/haveyoudebuggedit/example", "version": "", "test": "", "elapsed": "0s", - "output": "bm8gdGVzdCBmaWxlcw==", + "output": null, "cached": false, "coverage": null }, { - "action": "run", + "action": "stdout", "package": "", "version": "", - "test": "TestSleep", + "test": "", "elapsed": "0s", - "output": null, + "output": "bm90aGluZ190ZXN0LmdvOjc6MTE6IGV4cGVjdGVkICcoJywgZm91bmQgTm90aGluZw==", "cached": false, "coverage": null }, { - "action": "stdout", - "package": "", + "action": "fail", + "package": "github.com/haveyoudebuggedit/example", "version": "", "test": "", "elapsed": "0s", - "output": "ICAgIHNsZWVwX3Rlc3QuZ286MTA6IE5vdyBzbGVlcGluZyBmb3IgNSBzZWNvbmRzLi4u", + "output": "c2V0dXAgZmFpbGVk", "cached": false, "coverage": null }, { - "action": "stdout", - "package": "", + "action": "run", + "package": "github.com/haveyoudebuggedit/example/second", "version": "", - "test": "", + "test": "TestNothing", "elapsed": "0s", - "output": "ICAgIHNsZWVwX3Rlc3QuZ286MTI6IFdlbGNvbWUgYmFjaywgbm93IGZpbmlzaGluZyB0ZXN0Lg==", + "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "pass", - "package": "", + "package": "github.com/haveyoudebuggedit/example/second", "version": "", - "test": "TestSleep", - "elapsed": "5s", + "test": "TestNothing", + "elapsed": "0s", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "pass-final", - "package": "", + "package": "github.com/haveyoudebuggedit/example/second", "version": "", "test": "", "elapsed": "0s", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "pass", - "package": "github.com/haveyoudebuggedit/gotestfmt/testutil", + "package": "github.com/haveyoudebuggedit/example/second", "version": "", "test": "", - "elapsed": "5.003s", + "elapsed": "2ms", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true } ] \ No newline at end of file diff --git a/testdata/multipackage-syntax-json.txt b/testdata/multipackage-syntax-json.txt new file mode 100644 index 0000000..0d94521 --- /dev/null +++ b/testdata/multipackage-syntax-json.txt @@ -0,0 +1,10 @@ +# github.com/haveyoudebuggedit/example +nothing_test.go:7:11: expected '(', found Nothing +FAIL github.com/haveyoudebuggedit/example [setup failed] +{"Time":"2021-11-27T10:23:01.309620888+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example/second","Test":"TestNothing"} +{"Time":"2021-11-27T10:23:01.309734731+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/second","Test":"TestNothing","Output":"=== RUN TestNothing\n"} +{"Time":"2021-11-27T10:23:01.3097659+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/second","Test":"TestNothing","Output":"--- PASS: TestNothing (0.00s)\n"} +{"Time":"2021-11-27T10:23:01.309786588+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example/second","Test":"TestNothing","Elapsed":0} +{"Time":"2021-11-27T10:23:01.309799132+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/second","Output":"PASS\n"} +{"Time":"2021-11-27T10:23:01.309994377+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/second","Output":"ok \tgithub.com/haveyoudebuggedit/example/second\t0.002s\n"} +{"Time":"2021-11-27T10:23:01.310211915+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example/second","Elapsed":0.002} \ No newline at end of file diff --git a/testdata/parallel.parser.json b/testdata/parallel.parser.json index 5c11d45..5088c47 100644 --- a/testdata/parallel.parser.json +++ b/testdata/parallel.parser.json @@ -6,19 +6,19 @@ { "name": "github.com/haveyoudebuggedit/example", "result": "PASS", - "duration": "10.048s", + "duration": "10.01s", "testcases": [ { "name": "TestParallel1", "result": "PASS", "output": " parallel_test.go:10: Test message 1\n parallel_test.go:12: Test message 2", - "duration": "5.01s" + "duration": "5s" }, { "name": "TestParallel2", "result": "PASS", "output": " parallel_test.go:18: Test message 1\n parallel_test.go:20: Test message 2", - "duration": "10.02s" + "duration": "10.01s" } ] } diff --git a/testdata/parallel.tokenizer.json b/testdata/parallel.tokenizer.json index e5b4f7e..da9b625 100644 --- a/testdata/parallel.tokenizer.json +++ b/testdata/parallel.tokenizer.json @@ -1,68 +1,178 @@ [ { "action": "run", - "test": "TestParallel1" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel1", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "pause", - "test": "TestParallel1" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel1", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "run", - "test": "TestParallel2" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel2", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "pause", - "test": "TestParallel2" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel2", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "cont", - "test": "TestParallel1" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel1", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "stdout", - "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MTA6IFRlc3QgbWVzc2FnZSAx" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel1", + "elapsed": "0s", + "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MTA6IFRlc3QgbWVzc2FnZSAx", + "cached": false, + "coverage": null, + "json": true }, { "action": "cont", - "test": "TestParallel2" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel2", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true + }, + { + "action": "stdout", + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel2", + "elapsed": "0s", + "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MTg6IFRlc3QgbWVzc2FnZSAx", + "cached": false, + "coverage": null, + "json": true }, { "action": "cont", - "test": "TestParallel1" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel1", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "stdout", - "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MTI6IFRlc3QgbWVzc2FnZSAy" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel1", + "elapsed": "0s", + "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MTI6IFRlc3QgbWVzc2FnZSAy", + "cached": false, + "coverage": null, + "json": true }, { "action": "pass", + "package": "github.com/haveyoudebuggedit/example", + "version": "", "test": "TestParallel1", - "elapsed": "5.010s" + "elapsed": "5s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "cont", - "test": "TestParallel2" - }, - { - "action": "stdout", - "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MTg6IFRlc3QgbWVzc2FnZSAx" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel2", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "stdout", - "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MjA6IFRlc3QgbWVzc2FnZSAy" + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestParallel2", + "elapsed": "0s", + "output": "ICAgIHBhcmFsbGVsX3Rlc3QuZ286MjA6IFRlc3QgbWVzc2FnZSAy", + "cached": false, + "coverage": null, + "json": true }, { "action": "pass", + "package": "github.com/haveyoudebuggedit/example", + "version": "", "test": "TestParallel2", - "elapsed": "10.020s" + "elapsed": "10.01s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { - "action": "pass-final" + "action": "pass-final", + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "pass", "package": "github.com/haveyoudebuggedit/example", - "elapsed": "10.048s" + "version": "", + "test": "", + "elapsed": "10.01s", + "output": null, + "cached": false, + "coverage": null, + "json": true } ] \ No newline at end of file diff --git a/testdata/parallel.txt b/testdata/parallel.txt index 76b407b..b5cb6d6 100644 --- a/testdata/parallel.txt +++ b/testdata/parallel.txt @@ -1,16 +1,27 @@ -=== RUN TestParallel1 -=== PAUSE TestParallel1 -=== RUN TestParallel2 -=== PAUSE TestParallel2 -=== CONT TestParallel1 - parallel_test.go:10: Test message 1 -=== CONT TestParallel2 -=== CONT TestParallel1 - parallel_test.go:12: Test message 2 ---- PASS: TestParallel1 (5.01s) -=== CONT TestParallel2 - parallel_test.go:18: Test message 1 - parallel_test.go:20: Test message 2 ---- PASS: TestParallel2 (10.02s) -PASS -ok github.com/haveyoudebuggedit/example 10.048s \ No newline at end of file +{"Time":"2021-12-04T16:33:13.602687968+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1"} +{"Time":"2021-12-04T16:33:13.60280686+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Output":"=== RUN TestParallel1\n"} +{"Time":"2021-12-04T16:33:13.602853207+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Output":"=== PAUSE TestParallel1\n"} +{"Time":"2021-12-04T16:33:13.602874287+01:00","Action":"pause","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1"} +{"Time":"2021-12-04T16:33:13.602895597+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2"} +{"Time":"2021-12-04T16:33:13.602916766+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Output":"=== RUN TestParallel2\n"} +{"Time":"2021-12-04T16:33:13.602923819+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Output":"=== PAUSE TestParallel2\n"} +{"Time":"2021-12-04T16:33:13.602940461+01:00","Action":"pause","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2"} +{"Time":"2021-12-04T16:33:13.60296684+01:00","Action":"cont","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1"} +{"Time":"2021-12-04T16:33:13.602986487+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Output":"=== CONT TestParallel1\n"} +{"Time":"2021-12-04T16:33:13.603007536+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Output":" parallel_test.go:10: Test message 1\n"} +{"Time":"2021-12-04T16:33:13.603029497+01:00","Action":"cont","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2"} +{"Time":"2021-12-04T16:33:13.603049966+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Output":"=== CONT TestParallel2\n"} +{"Time":"2021-12-04T16:33:18.606953185+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Output":" parallel_test.go:18: Test message 1\n"} +{"Time":"2021-12-04T16:33:18.607013277+01:00","Action":"cont","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1"} +{"Time":"2021-12-04T16:33:18.60702008+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Output":"=== CONT TestParallel1\n"} +{"Time":"2021-12-04T16:33:18.60705236+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Output":" parallel_test.go:12: Test message 2\n"} +{"Time":"2021-12-04T16:33:18.607088618+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Output":"--- PASS: TestParallel1 (5.00s)\n"} +{"Time":"2021-12-04T16:33:23.611091294+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel1","Elapsed":5} +{"Time":"2021-12-04T16:33:23.61114797+01:00","Action":"cont","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2"} +{"Time":"2021-12-04T16:33:23.611154402+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Output":"=== CONT TestParallel2\n"} +{"Time":"2021-12-04T16:33:23.61115889+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Output":" parallel_test.go:20: Test message 2\n"} +{"Time":"2021-12-04T16:33:23.61116407+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Output":"--- PASS: TestParallel2 (10.01s)\n"} +{"Time":"2021-12-04T16:33:23.611166304+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Test":"TestParallel2","Elapsed":10.01} +{"Time":"2021-12-04T16:33:23.611169851+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"PASS\n"} +{"Time":"2021-12-04T16:33:23.611488959+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"ok \tgithub.com/haveyoudebuggedit/example\t10.010s\n"} +{"Time":"2021-12-04T16:33:23.611781026+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Elapsed":10.01} \ No newline at end of file diff --git a/testdata/single-package-verbose.parser.json b/testdata/single-package-verbose.parser.json deleted file mode 100644 index 57ddce4..0000000 --- a/testdata/single-package-verbose.parser.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "downloads": { - "failed": false - }, - "packages": [ - { - "name": "github.com/haveyoudebuggedit/example", - "result": "PASS", - "duration": "0.019s", - "testcases": [ - { - "name": "TestNothing", - "result": "PASS" - } - ] - } - ] -} \ No newline at end of file diff --git a/testdata/single-package-verbose.tokenizer.json b/testdata/single-package-verbose.tokenizer.json deleted file mode 100644 index 625b5e2..0000000 --- a/testdata/single-package-verbose.tokenizer.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "action": "run", - "test": "TestNothing" - }, - { - "action": "pass", - "test": "TestNothing" - }, - { - "action": "pass-final" - }, - { - "action": "pass", - "package": "github.com/haveyoudebuggedit/example", - "elapsed": "0.019s" - } -] diff --git a/testdata/single-package-verbose.txt b/testdata/single-package-verbose.txt deleted file mode 100644 index aa58521..0000000 --- a/testdata/single-package-verbose.txt +++ /dev/null @@ -1,4 +0,0 @@ -=== RUN TestNothing ---- PASS: TestNothing (0.00s) -PASS -ok github.com/haveyoudebuggedit/example 0.019s \ No newline at end of file diff --git a/testdata/single-package.parser.json b/testdata/single-package.parser.json deleted file mode 100644 index cf29e5d..0000000 --- a/testdata/single-package.parser.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "downloads": { - "failed": false - }, - "packages": [ - { - "name": "github.com/haveyoudebuggedit/example", - "result": "PASS", - "duration": "0.019s" - } - ] -} \ No newline at end of file diff --git a/testdata/single-package.tokenizer.json b/testdata/single-package.tokenizer.json deleted file mode 100644 index d1757ef..0000000 --- a/testdata/single-package.tokenizer.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "action": "pass", - "package": "github.com/haveyoudebuggedit/example", - "elapsed": "0.019s" - } -] diff --git a/testdata/single-package.txt b/testdata/single-package.txt deleted file mode 100644 index dae371e..0000000 --- a/testdata/single-package.txt +++ /dev/null @@ -1 +0,0 @@ -ok github.com/haveyoudebuggedit/example 0.019s \ No newline at end of file diff --git a/testdata/skip.parser.json b/testdata/skip.parser.json new file mode 100644 index 0000000..92c975d --- /dev/null +++ b/testdata/skip.parser.json @@ -0,0 +1,24 @@ +{ + "downloads": { + "failed": false + }, + "packages": [ + { + "name": "github.com/haveyoudebuggedit/example", + "result": "PASS", + "duration": "0s", + "coverage": null, + "output": "", + "testcases": [ + { + "name": "TestSkip", + "result": "SKIP", + "duration": "0s", + "coverage": null, + "output": "" + } + ], + "reason": "" + } + ] +} \ No newline at end of file diff --git a/testdata/skip.tokenizer.json b/testdata/skip.tokenizer.json new file mode 100644 index 0000000..32b1f91 --- /dev/null +++ b/testdata/skip.tokenizer.json @@ -0,0 +1,46 @@ +[ + { + "action": "run", + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestSkip", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true + }, + { + "action": "skip", + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "TestSkip", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true + }, + { + "action": "pass-final", + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true + }, + { + "action": "pass", + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "", + "elapsed": "0s", + "output": null, + "cached": true, + "coverage": null, + "json": true + } +] \ No newline at end of file diff --git a/testdata/skip.txt b/testdata/skip.txt new file mode 100644 index 0000000..506a80c --- /dev/null +++ b/testdata/skip.txt @@ -0,0 +1,7 @@ +{"Time":"2021-12-05T07:00:44.938993+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestSkip"} +{"Time":"2021-12-05T07:00:44.93952+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSkip","Output":"=== RUN TestSkip\n"} +{"Time":"2021-12-05T07:00:44.9400465+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSkip","Output":"--- SKIP: TestSkip (0.00s)\n"} +{"Time":"2021-12-05T07:00:44.9400465+01:00","Action":"skip","Package":"github.com/haveyoudebuggedit/example","Test":"TestSkip","Elapsed":0} +{"Time":"2021-12-05T07:00:44.9400465+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"PASS\n"} +{"Time":"2021-12-05T07:00:44.9405733+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"ok \tgithub.com/haveyoudebuggedit/example\t(cached)\n"} +{"Time":"2021-12-05T07:00:44.9405733+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Elapsed":0.002} \ No newline at end of file diff --git a/testdata/subtest.parser.json b/testdata/subtest.parser.json index 2b75d7c..28d999f 100644 --- a/testdata/subtest.parser.json +++ b/testdata/subtest.parser.json @@ -6,7 +6,7 @@ { "name": "github.com/haveyoudebuggedit/example", "result": "FAIL", - "duration": "0.020s", + "duration": "0.103s", "testcases": [ { "name": "TestSubtest", diff --git a/testdata/subtest.tokenizer.json b/testdata/subtest.tokenizer.json index e927f9c..e8e85b5 100644 --- a/testdata/subtest.tokenizer.json +++ b/testdata/subtest.tokenizer.json @@ -1,57 +1,82 @@ [ { "action": "run", - "test": "TestSubtest" + "test": "TestSubtest", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "run", - "test": "TestSubtest/test1" + "test": "TestSubtest/test1", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "stdout", - "output": "ICAgIHN1YnRlc3RfdGVzdC5nbzo5OiBIZWxsbyB3b3JsZCE=" + "output": "ICAgIHN1YnRlc3RfdGVzdC5nbzo5OiBIZWxsbyB3b3JsZCE=", + "package": "github.com/haveyoudebuggedit/example", + "test": "TestSubtest/test1", + "json": true }, { "action": "run", - "test": "TestSubtest/test2" + "test": "TestSubtest/test2", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "stdout", - "output": "ICAgIHN1YnRlc3RfdGVzdC5nbzoxMjogSGVyZSdzIGFuIGVycm9yLg==" + "output": "ICAgIHN1YnRlc3RfdGVzdC5nbzoxMjogSGVyZSdzIGFuIGVycm9yLg==", + "package": "github.com/haveyoudebuggedit/example", + "test": "TestSubtest/test2", + "json": true }, { "action": "run", - "test": "TestSubtest/test3" + "test": "TestSubtest/test3", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "stdout", - "output": "ICAgIHN1YnRlc3RfdGVzdC5nbzoxNTogTGV0J3Mgc2tpcCB0aGlzIG9uZS4uLg==" + "output": "ICAgIHN1YnRlc3RfdGVzdC5nbzoxNTogTGV0J3Mgc2tpcCB0aGlzIG9uZS4uLg==", + "package": "github.com/haveyoudebuggedit/example", + "test": "TestSubtest/test3", + "json": true }, { "action": "fail", - "test": "TestSubtest" + "package": "github.com/haveyoudebuggedit/example", + "test": "TestSubtest", + "json": true }, { "action": "pass", - "test": "TestSubtest/test1" + "test": "TestSubtest/test1", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "fail", - "test": "TestSubtest/test2" + "test": "TestSubtest/test2", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "skip", - "test": "TestSubtest/test3" + "test": "TestSubtest/test3", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { - "action": "fail-final" + "action": "fail-final", + "package": "github.com/haveyoudebuggedit/example", + "json": true }, { "action": "fail", "package": "github.com/haveyoudebuggedit/example", - "elapsed": "0.020s" - }, - { - "action": "fail-final" + "elapsed": "0.103s", + "json": true } ] \ No newline at end of file diff --git a/testdata/subtest.txt b/testdata/subtest.txt index 12889b9..d608d36 100644 --- a/testdata/subtest.txt +++ b/testdata/subtest.txt @@ -1,14 +1,22 @@ -=== RUN TestSubtest -=== RUN TestSubtest/test1 - subtest_test.go:9: Hello world! -=== RUN TestSubtest/test2 - subtest_test.go:12: Here's an error. -=== RUN TestSubtest/test3 - subtest_test.go:15: Let's skip this one... ---- FAIL: TestSubtest (0.00s) - --- PASS: TestSubtest/test1 (0.00s) - --- FAIL: TestSubtest/test2 (0.00s) - --- SKIP: TestSubtest/test3 (0.00s) -FAIL -FAIL github.com/haveyoudebuggedit/example 0.020s -FAIL \ No newline at end of file +{"Time":"2021-12-05T07:01:25.3314854+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest"} +{"Time":"2021-12-05T07:01:25.3320042+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest","Output":"=== RUN TestSubtest\n"} +{"Time":"2021-12-05T07:01:25.3320042+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test1"} +{"Time":"2021-12-05T07:01:25.3320042+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test1","Output":"=== RUN TestSubtest/test1\n"} +{"Time":"2021-12-05T07:01:25.3330012+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test1","Output":" subtest_test.go:9: Hello world!\n"} +{"Time":"2021-12-05T07:01:25.3330012+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test2"} +{"Time":"2021-12-05T07:01:25.3330012+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test2","Output":"=== RUN TestSubtest/test2\n"} +{"Time":"2021-12-05T07:01:25.3330012+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test2","Output":" subtest_test.go:12: Here's an error.\n"} +{"Time":"2021-12-05T07:01:25.3330012+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test3"} +{"Time":"2021-12-05T07:01:25.3330012+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test3","Output":"=== RUN TestSubtest/test3\n"} +{"Time":"2021-12-05T07:01:25.3339997+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test3","Output":" subtest_test.go:15: Let's skip this one...\n"} +{"Time":"2021-12-05T07:01:25.3339997+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest","Output":"--- FAIL: TestSubtest (0.00s)\n"} +{"Time":"2021-12-05T07:01:25.3339997+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test1","Output":" --- PASS: TestSubtest/test1 (0.00s)\n"} +{"Time":"2021-12-05T07:01:25.3339997+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test1","Elapsed":0} +{"Time":"2021-12-05T07:01:25.3339997+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test2","Output":" --- FAIL: TestSubtest/test2 (0.00s)\n"} +{"Time":"2021-12-05T07:01:25.3339997+01:00","Action":"fail","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test2","Elapsed":0} +{"Time":"2021-12-05T07:01:25.3349996+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test3","Output":" --- SKIP: TestSubtest/test3 (0.00s)\n"} +{"Time":"2021-12-05T07:01:25.3349996+01:00","Action":"skip","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest/test3","Elapsed":0} +{"Time":"2021-12-05T07:01:25.3349996+01:00","Action":"fail","Package":"github.com/haveyoudebuggedit/example","Test":"TestSubtest","Elapsed":0} +{"Time":"2021-12-05T07:01:25.3349996+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"FAIL\n"} +{"Time":"2021-12-05T07:01:25.3380014+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"FAIL\tgithub.com/haveyoudebuggedit/example\t0.103s\n"} +{"Time":"2021-12-05T07:01:25.3380014+01:00","Action":"fail","Package":"github.com/haveyoudebuggedit/example","Elapsed":0.104} \ No newline at end of file diff --git a/testdata/testify.parser.json b/testdata/testify.parser.json index 5fd32c1..fad0429 100644 --- a/testdata/testify.parser.json +++ b/testdata/testify.parser.json @@ -8,7 +8,7 @@ { "name": "github.com/haveyoudebuggedit/example", "result": "FAIL", - "duration": "71ms", + "duration": "162ms", "coverage": null, "output": "", "testcases": [ @@ -17,7 +17,7 @@ "result": "FAIL", "duration": "0s", "coverage": null, - "output": " testify_test.go:10:\n Error Trace: testify_test.go:10\n Error: Not equal:\n expected: 50\n actual : 48\n Test: TestTestify" + "output": " testify_test.go:10: \n \tError Trace:\ttestify_test.go:10\n \tError: \tNot equal: \n \t \texpected: 50\n \t \tactual : 48\n \tTest: \tTestTestify" } ], "reason": "" diff --git a/testdata/testify.tokenizer.json b/testdata/testify.tokenizer.json index 2689c11..a52c42a 100644 --- a/testdata/testify.tokenizer.json +++ b/testdata/testify.tokenizer.json @@ -1,98 +1,112 @@ [ { - "action": "fail", - "package": "", + "action": "run", + "package": "github.com/haveyoudebuggedit/example", "version": "", "test": "TestTestify", "elapsed": "0s", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgIHRlc3RpZnlfdGVzdC5nbzoxMDo=", + "output": "ICAgIHRlc3RpZnlfdGVzdC5nbzoxMDog", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgIEVycm9yIFRyYWNlOiAgICB0ZXN0aWZ5X3Rlc3QuZ286MTA=", + "output": "ICAgICAgICAJRXJyb3IgVHJhY2U6CXRlc3RpZnlfdGVzdC5nbzoxMA==", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgIEVycm9yOiAgICAgICAgICBOb3QgZXF1YWw6", + "output": "ICAgICAgICAJRXJyb3I6ICAgICAgCU5vdCBlcXVhbDog", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogNTA=", + "output": "ICAgICAgICAJICAgICAgICAgICAgCWV4cGVjdGVkOiA1MA==", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWwgIDogNDg=", + "output": "ICAgICAgICAJICAgICAgICAgICAgCWFjdHVhbCAgOiA0OA==", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgIFRlc3Q6ICAgICAgICAgICBUZXN0VGVzdGlmeQ==", + "output": "ICAgICAgICAJVGVzdDogICAgICAgCVRlc3RUZXN0aWZ5", "cached": false, - "coverage": null - }, - { - "action": "fail-final" + "coverage": null, + "json": true }, { "action": "fail", "package": "github.com/haveyoudebuggedit/example", "version": "", - "test": "", - "elapsed": "71ms", + "test": "TestTestify", + "elapsed": "0s", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { - "action": "fail-final" + "action": "fail-final", + "package": "github.com/haveyoudebuggedit/example", + "version": "", + "test": "", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { - "action": "stdout", - "package": "", + "action": "fail", + "package": "github.com/haveyoudebuggedit/example", "version": "", "test": "", - "elapsed": "0s", - "output": "", + "elapsed": "162ms", + "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true } ] \ No newline at end of file diff --git a/testdata/testify.txt b/testdata/testify.txt index 5c5e95b..8b87e14 100644 --- a/testdata/testify.txt +++ b/testdata/testify.txt @@ -1,10 +1,13 @@ ---- FAIL: TestTestify (0.00s) - testify_test.go:10: - Error Trace: testify_test.go:10 - Error: Not equal: - expected: 50 - actual : 48 - Test: TestTestify -FAIL -FAIL github.com/haveyoudebuggedit/example 0.071s -FAIL +{"Time":"2021-12-05T07:01:59.782579+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify"} +{"Time":"2021-12-05T07:01:59.7831013+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":"=== RUN TestTestify\n"} +{"Time":"2021-12-05T07:01:59.7831013+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":" testify_test.go:10: \n"} +{"Time":"2021-12-05T07:01:59.7831013+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":" \tError Trace:\ttestify_test.go:10\n"} +{"Time":"2021-12-05T07:01:59.7840992+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":" \tError: \tNot equal: \n"} +{"Time":"2021-12-05T07:01:59.7840992+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":" \t \texpected: 50\n"} +{"Time":"2021-12-05T07:01:59.7840992+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":" \t \tactual : 48\n"} +{"Time":"2021-12-05T07:01:59.7840992+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":" \tTest: \tTestTestify\n"} +{"Time":"2021-12-05T07:01:59.7840992+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Output":"--- FAIL: TestTestify (0.00s)\n"} +{"Time":"2021-12-05T07:01:59.7840992+01:00","Action":"fail","Package":"github.com/haveyoudebuggedit/example","Test":"TestTestify","Elapsed":0} +{"Time":"2021-12-05T07:01:59.7840992+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"FAIL\n"} +{"Time":"2021-12-05T07:01:59.7900979+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example","Output":"FAIL\tgithub.com/haveyoudebuggedit/example\t0.162s\n"} +{"Time":"2021-12-05T07:01:59.7900979+01:00","Action":"fail","Package":"github.com/haveyoudebuggedit/example","Elapsed":0.162} \ No newline at end of file diff --git a/testdata/testifymultipackage.parser.json b/testdata/testifymultipackage.parser.json index c74e272..1b3b912 100644 --- a/testdata/testifymultipackage.parser.json +++ b/testdata/testifymultipackage.parser.json @@ -8,16 +8,24 @@ { "name": "github.com/haveyoudebuggedit/example/subpackage1", "result": "PASS", - "duration": "75ms", + "duration": "168ms", "coverage": null, "output": "", - "testcases": null, + "testcases": [ + { + "name": "TestTestify", + "result": "PASS", + "duration": "0s", + "coverage": null, + "output": "" + } + ], "reason": "" }, { "name": "github.com/haveyoudebuggedit/example/subpackage2", "result": "FAIL", - "duration": "75ms", + "duration": "168ms", "coverage": null, "output": "", "testcases": [ @@ -26,7 +34,7 @@ "result": "FAIL", "duration": "0s", "coverage": null, - "output": " testify_test.go:10:\n Error Trace: testify_test.go:10\n Error: Not equal:\n expected: 50\n actual : 48\n Test: TestTestify" + "output": " testify_test.go:10: \n \tError Trace:\ttestify_test.go:10\n \tError: \tNot equal: \n \t \texpected: 50\n \t \tactual : 48\n \tTest: \tTestTestify" } ], "reason": "" diff --git a/testdata/testifymultipackage.tokenizer.json b/testdata/testifymultipackage.tokenizer.json index b727551..af515de 100644 --- a/testdata/testifymultipackage.tokenizer.json +++ b/testdata/testifymultipackage.tokenizer.json @@ -1,98 +1,167 @@ [ { - "action": "pass", + "action": "run", "package": "github.com/haveyoudebuggedit/example/subpackage1", "version": "", - "test": "", - "elapsed": "75ms", + "test": "TestTestify", + "elapsed": "0s", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { - "action": "fail", - "package": "", + "action": "run", + "package": "github.com/haveyoudebuggedit/example/subpackage2", "version": "", "test": "TestTestify", "elapsed": "0s", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true + }, + { + "action": "pass", + "package": "github.com/haveyoudebuggedit/example/subpackage1", + "version": "", + "test": "TestTestify", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example/subpackage2", + "version": "", + "test": "TestTestify", + "elapsed": "0s", + "output": "ICAgIHRlc3RpZnlfdGVzdC5nbzoxMDog", + "cached": false, + "coverage": null, + "json": true + }, + { + "action": "pass-final", + "package": "github.com/haveyoudebuggedit/example/subpackage1", "version": "", "test": "", "elapsed": "0s", - "output": "ICAgIHRlc3RpZnlfdGVzdC5nbzoxMDo=", + "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example/subpackage2", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgIEVycm9yIFRyYWNlOiAgICB0ZXN0aWZ5X3Rlc3QuZ286MTA=", + "output": "ICAgICAgICAJRXJyb3IgVHJhY2U6CXRlc3RpZnlfdGVzdC5nbzoxMA==", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example/subpackage2", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgIEVycm9yOiAgICAgICAgICBOb3QgZXF1YWw6", + "output": "ICAgICAgICAJRXJyb3I6ICAgICAgCU5vdCBlcXVhbDog", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example/subpackage2", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogNTA=", + "output": "ICAgICAgICAJICAgICAgICAgICAgCWV4cGVjdGVkOiA1MA==", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example/subpackage2", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWwgIDogNDg=", + "output": "ICAgICAgICAJICAgICAgICAgICAgCWFjdHVhbCAgOiA0OA==", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { "action": "stdout", - "package": "", + "package": "github.com/haveyoudebuggedit/example/subpackage2", "version": "", - "test": "", + "test": "TestTestify", "elapsed": "0s", - "output": "ICAgICAgICAgICAgICAgIFRlc3Q6ICAgICAgICAgICBUZXN0VGVzdGlmeQ==", + "output": "ICAgICAgICAJVGVzdDogICAgICAgCVRlc3RUZXN0aWZ5", "cached": false, - "coverage": null + "coverage": null, + "json": true }, { - "action": "fail-final" + "action": "fail", + "package": "github.com/haveyoudebuggedit/example/subpackage2", + "version": "", + "test": "TestTestify", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true + }, + { + "action": "fail-final", + "package": "github.com/haveyoudebuggedit/example/subpackage2", + "version": "", + "test": "", + "elapsed": "0s", + "output": null, + "cached": false, + "coverage": null, + "json": true }, { "action": "fail", "package": "github.com/haveyoudebuggedit/example/subpackage2", "version": "", "test": "", - "elapsed": "75ms", + "elapsed": "168ms", + "output": null, + "cached": false, + "coverage": null, + "json": true + }, + { + "action": "pass", + "package": "github.com/haveyoudebuggedit/example/subpackage1", + "version": "", + "test": "", + "elapsed": "168ms", "output": null, "cached": false, - "coverage": null + "coverage": null, + "json": true }, { - "action": "fail-final" + "action": "stdout", + "package": "", + "version": "", + "test": "", + "elapsed": "0s", + "output": "", + "cached": false, + "coverage": null, + "json": false } ] \ No newline at end of file diff --git a/testdata/testifymultipackage.txt b/testdata/testifymultipackage.txt index f93902e..569d0e2 100644 --- a/testdata/testifymultipackage.txt +++ b/testdata/testifymultipackage.txt @@ -1,11 +1,20 @@ -ok github.com/haveyoudebuggedit/example/subpackage1 0.075s ---- FAIL: TestTestify (0.00s) - testify_test.go:10: - Error Trace: testify_test.go:10 - Error: Not equal: - expected: 50 - actual : 48 - Test: TestTestify -FAIL -FAIL github.com/haveyoudebuggedit/example/subpackage2 0.075s -FAIL \ No newline at end of file +{"Time":"2021-12-05T07:02:32.554971+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify"} +{"Time":"2021-12-05T07:02:32.554971+01:00","Action":"run","Package":"github.com/haveyoudebuggedit/example/subpackage1","Test":"TestTestify"} +{"Time":"2021-12-05T07:02:32.5554993+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage1","Test":"TestTestify","Output":"=== RUN TestTestify\n"} +{"Time":"2021-12-05T07:02:32.5554993+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":"=== RUN TestTestify\n"} +{"Time":"2021-12-05T07:02:32.5554993+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage1","Test":"TestTestify","Output":"--- PASS: TestTestify (0.00s)\n"} +{"Time":"2021-12-05T07:02:32.5564942+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":" testify_test.go:10: \n"} +{"Time":"2021-12-05T07:02:32.5564942+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example/subpackage1","Test":"TestTestify","Elapsed":0} +{"Time":"2021-12-05T07:02:32.5564942+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage1","Output":"PASS\n"} +{"Time":"2021-12-05T07:02:32.5564942+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":" \tError Trace:\ttestify_test.go:10\n"} +{"Time":"2021-12-05T07:02:32.5564942+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":" \tError: \tNot equal: \n"} +{"Time":"2021-12-05T07:02:32.5574943+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":" \t \texpected: 50\n"} +{"Time":"2021-12-05T07:02:32.5574943+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":" \t \tactual : 48\n"} +{"Time":"2021-12-05T07:02:32.5574943+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":" \tTest: \tTestTestify\n"} +{"Time":"2021-12-05T07:02:32.5574943+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Output":"--- FAIL: TestTestify (0.00s)\n"} +{"Time":"2021-12-05T07:02:32.5574943+01:00","Action":"fail","Package":"github.com/haveyoudebuggedit/example/subpackage2","Test":"TestTestify","Elapsed":0} +{"Time":"2021-12-05T07:02:32.5574943+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Output":"FAIL\n"} +{"Time":"2021-12-05T07:02:32.5621827+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage2","Output":"FAIL\tgithub.com/haveyoudebuggedit/example/subpackage2\t0.168s\n"} +{"Time":"2021-12-05T07:02:32.5621827+01:00","Action":"output","Package":"github.com/haveyoudebuggedit/example/subpackage1","Output":"ok \tgithub.com/haveyoudebuggedit/example/subpackage1\t0.168s\n"} +{"Time":"2021-12-05T07:02:32.5621827+01:00","Action":"fail","Package":"github.com/haveyoudebuggedit/example/subpackage2","Elapsed":0.168} +{"Time":"2021-12-05T07:02:32.5731844+01:00","Action":"pass","Package":"github.com/haveyoudebuggedit/example/subpackage1","Elapsed":0.179} diff --git a/tokenizer/event.go b/tokenizer/event.go index 3061606..a804f5c 100644 --- a/tokenizer/event.go +++ b/tokenizer/event.go @@ -27,6 +27,8 @@ type Event struct { Cached bool `json:"cached"` // Coverage shows the code coverage. Coverage *float64 `json:"coverage"` + // JSON indicates if the event was sent using a JSON-encoded test. + JSON bool `json:"json"` } func (e Event) Equals(o Event) bool { @@ -36,6 +38,7 @@ func (e Event) Equals(o Event) bool { e.Test == o.Test && e.Elapsed == o.Elapsed && e.Cached == o.Cached && + e.JSON == o.JSON && (e.Coverage == o.Coverage || (e.Coverage != nil && o.Coverage != nil && *e.Coverage == *o.Coverage)) && bytes.Equal(e.Output, o.Output) @@ -66,6 +69,8 @@ type tmpEvent struct { Cached bool `json:"cached"` // Coverage shows the code coverage. Coverage *float64 `json:"coverage"` + // JSON indicates that the event was JSON-encoded. + JSON bool `json:"json"` } func (e *Event) UnmarshalJSON(data []byte) error { @@ -91,6 +96,7 @@ func (e *Event) UnmarshalJSON(data []byte) error { e.Output = tmp.Output e.Cached = tmp.Cached e.Coverage = tmp.Coverage + e.JSON = tmp.JSON return nil } @@ -104,6 +110,7 @@ func (e *Event) MarshalJSON() ([]byte, error) { Output: e.Output, Cached: e.Cached, Coverage: e.Coverage, + JSON: e.JSON, } return json.Marshal(tmp) } diff --git a/tokenizer/tokenizer.go b/tokenizer/tokenizer.go index 16b38f2..524c3d0 100644 --- a/tokenizer/tokenizer.go +++ b/tokenizer/tokenizer.go @@ -2,11 +2,13 @@ package tokenizer import ( "bytes" + "encoding/json" "errors" "fmt" "io" "regexp" "strconv" + "strings" "time" ) @@ -70,6 +72,12 @@ var stateMachine = []stateChange{ ActionRun, stateRun, }, + { + regexp.MustCompile(`^=== RUN\s+(?P.*)$`), + stateBetweenTests, + ActionRun, + stateRun, + }, { regexp.MustCompile(`^=== PAUSE\s+(?P.*)$`), stateRun, @@ -328,7 +336,29 @@ func decode(input io.Reader, output chan<- Event) { _ = parseLine(currentState, lastBuffer, output) } +func tryParseJSONLine(line []byte) *jsonTestEvent { + if len(line) == 0 || line[0] != 123 { + return nil + } + + // Try to decode JSON line + decoder := json.NewDecoder(bytes.NewReader(line)) + jsonLine := &jsonTestEvent{} + if err := decoder.Decode(jsonLine); err != nil { + return nil + } + return jsonLine +} + func parseLine(currentState state, line []byte, output chan<- Event) state { + jsonLine := tryParseJSONLine(line) + if jsonLine != nil { + if jsonLine.Output == nil { + return currentState + } + line = []byte(strings.TrimRight(*jsonLine.Output, "\r\n")) + } + for _, stateTransition := range stateMachine { if stateTransition.inputState != currentState { continue @@ -350,16 +380,34 @@ func parseLine(currentState state, line []byte, output chan<- Event) state { coveragePtr = &coverage } + pkg := string(extract(stateTransition.regexp, match, "Package")) + if jsonLine != nil && pkg == "" { + pkg = jsonLine.Package + } + version := string(extract(stateTransition.regexp, match, "Version")) + test := string(extract(stateTransition.regexp, match, "Test")) + if jsonLine != nil && test == "" { + test = jsonLine.Test + } + cached := string(extract(stateTransition.regexp, match, "Cached")) == "cached" + received := time.Now() + if jsonLine != nil && jsonLine.Time != nil { + received = *jsonLine.Time + } + if jsonLine != nil && jsonLine.Elapsed != nil && *jsonLine.Elapsed > 0 { + elapsed = time.Duration(*jsonLine.Elapsed * float64(time.Second)) + } evt := Event{ - Received: time.Now(), + Received: received, Action: stateTransition.action, - Package: string(extract(stateTransition.regexp, match, "Package")), - Version: string(extract(stateTransition.regexp, match, "Version")), - Test: string(extract(stateTransition.regexp, match, "Test")), - Cached: string(extract(stateTransition.regexp, match, "Cached")) == "cached", + Package: pkg, + Version: version, + Test: test, + Cached: cached, Coverage: coveragePtr, Elapsed: elapsed, Output: extract(stateTransition.regexp, match, "Output"), + JSON: jsonLine != nil, } output <- evt @@ -388,3 +436,12 @@ func extract(r *regexp.Regexp, match [][]byte, name string) []byte { } return match[idx] } + +type jsonTestEvent struct { + Time *time.Time `json:",omitempty"` + Action string + Package string `json:",omitempty"` + Test string `json:",omitempty"` + Elapsed *float64 `json:",omitempty"` + Output *string `json:",omitempty"` +}