build(deps): bump github.com/onsi/ginkgo/v2 from 2.25.3 to 2.26.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.25.3 to 2.26.0. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v2.25.3...v2.26.0) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo/v2 dependency-version: 2.26.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
4e06b0c376
commit
4c00db867c
+6
@@ -1,3 +1,9 @@
|
||||
## 2.26.0
|
||||
|
||||
### Features
|
||||
|
||||
Ginkgo can now generate json-formatted reports that are compatible with the `go test` json format. Use `ginkgo --gojson-report=report.go.json`. This is not intended to be a replacement for Ginkgo's native json format which is more information rich and better models Ginkgo's test structure semantics.
|
||||
|
||||
## 2.25.3
|
||||
|
||||
### Fixes
|
||||
|
||||
+10
@@ -113,3 +113,13 @@ Ginkgo is MIT-Licensed
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
## Sponsors
|
||||
|
||||
Sponsors commit to a [sponsorship](https://github.com/sponsors/onsi) for a year. If you're an organization that makes use of Ginkgo please consider becoming a sponsor!
|
||||
|
||||
<p style="font-size:21px; color:black;">Browser testing via
|
||||
<a href="https://www.lambdatest.com/" target="_blank">
|
||||
<img src="https://www.lambdatest.com/blue-logo.png" style="vertical-align: middle;" width="250" height="45" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
+3
@@ -90,6 +90,9 @@ func FinalizeProfilesAndReportsForSuites(suites TestSuites, cliConfig types.CLIC
|
||||
if reporterConfig.JSONReport != "" {
|
||||
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JSONReport, GenerateFunc: reporters.GenerateJSONReport, MergeFunc: reporters.MergeAndCleanupJSONReports})
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.GoJSONReport, GenerateFunc: reporters.GenerateGoTestJSONReport, MergeFunc: reporters.MergeAndCleanupGoTestJSONReports})
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
reportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JUnitReport, GenerateFunc: reporters.GenerateJUnitReport, MergeFunc: reporters.MergeAndCleanupJUnitReports})
|
||||
}
|
||||
|
||||
+6
@@ -107,6 +107,9 @@ func runSerial(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig t
|
||||
if reporterConfig.JSONReport != "" {
|
||||
reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
reporterConfig.GoJSONReport = AbsPathForGeneratedAsset(reporterConfig.GoJSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)
|
||||
}
|
||||
@@ -179,6 +182,9 @@ func runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig
|
||||
if reporterConfig.JSONReport != "" {
|
||||
reporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
reporterConfig.GoJSONReport = AbsPathForGeneratedAsset(reporterConfig.GoJSONReport, suite, cliConfig, 0)
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
reporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)
|
||||
}
|
||||
|
||||
-1
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
_ "go.uber.org/automaxprocs"
|
||||
"github.com/onsi/ginkgo/v2/ginkgo/build"
|
||||
"github.com/onsi/ginkgo/v2/ginkgo/command"
|
||||
"github.com/onsi/ginkgo/v2/ginkgo/generators"
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
//go:build !go1.25
|
||||
// +build !go1.25
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "go.uber.org/automaxprocs"
|
||||
)
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
package reporters
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
func ptr[T any](in T) *T {
|
||||
return &in
|
||||
}
|
||||
|
||||
type encoder interface {
|
||||
Encode(v any) error
|
||||
}
|
||||
|
||||
// gojsonEvent matches the format from go internals
|
||||
// https://github.com/golang/go/blob/master/src/cmd/internal/test2json/test2json.go#L31-L41
|
||||
// https://pkg.go.dev/cmd/test2json
|
||||
type gojsonEvent struct {
|
||||
Time *time.Time `json:",omitempty"`
|
||||
Action GoJSONAction
|
||||
Package string `json:",omitempty"`
|
||||
Test string `json:",omitempty"`
|
||||
Elapsed *float64 `json:",omitempty"`
|
||||
Output *string `json:",omitempty"`
|
||||
FailedBuild string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type GoJSONAction string
|
||||
|
||||
const (
|
||||
// start - the test binary is about to be executed
|
||||
GoJSONStart GoJSONAction = "start"
|
||||
// run - the test has started running
|
||||
GoJSONRun GoJSONAction = "run"
|
||||
// pause - the test has been paused
|
||||
GoJSONPause GoJSONAction = "pause"
|
||||
// cont - the test has continued running
|
||||
GoJSONCont GoJSONAction = "cont"
|
||||
// pass - the test passed
|
||||
GoJSONPass GoJSONAction = "pass"
|
||||
// bench - the benchmark printed log output but did not fail
|
||||
GoJSONBench GoJSONAction = "bench"
|
||||
// fail - the test or benchmark failed
|
||||
GoJSONFail GoJSONAction = "fail"
|
||||
// output - the test printed output
|
||||
GoJSONOutput GoJSONAction = "output"
|
||||
// skip - the test was skipped or the package contained no tests
|
||||
GoJSONSkip GoJSONAction = "skip"
|
||||
)
|
||||
|
||||
func goJSONActionFromSpecState(state types.SpecState) GoJSONAction {
|
||||
switch state {
|
||||
case types.SpecStateInvalid:
|
||||
return GoJSONFail
|
||||
case types.SpecStatePending:
|
||||
return GoJSONSkip
|
||||
case types.SpecStateSkipped:
|
||||
return GoJSONSkip
|
||||
case types.SpecStatePassed:
|
||||
return GoJSONPass
|
||||
case types.SpecStateFailed:
|
||||
return GoJSONFail
|
||||
case types.SpecStateAborted:
|
||||
return GoJSONFail
|
||||
case types.SpecStatePanicked:
|
||||
return GoJSONFail
|
||||
case types.SpecStateInterrupted:
|
||||
return GoJSONFail
|
||||
case types.SpecStateTimedout:
|
||||
return GoJSONFail
|
||||
default:
|
||||
panic("unexpected state should not happen")
|
||||
}
|
||||
}
|
||||
|
||||
// gojsonReport wraps types.Report and calcualtes extra fields requires by gojson
|
||||
type gojsonReport struct {
|
||||
o types.Report
|
||||
// Extra calculated fields
|
||||
goPkg string
|
||||
elapsed float64
|
||||
}
|
||||
|
||||
func newReport(in types.Report) *gojsonReport {
|
||||
return &gojsonReport{
|
||||
o: in,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *gojsonReport) Fill() error {
|
||||
// NOTE: could the types.Report include the go package name?
|
||||
goPkg, err := suitePathToPkg(r.o.SuitePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.goPkg = goPkg
|
||||
r.elapsed = r.o.RunTime.Seconds()
|
||||
return nil
|
||||
}
|
||||
|
||||
// gojsonSpecReport wraps types.SpecReport and calculates extra fields required by gojson
|
||||
type gojsonSpecReport struct {
|
||||
o types.SpecReport
|
||||
// extra calculated fields
|
||||
testName string
|
||||
elapsed float64
|
||||
action GoJSONAction
|
||||
}
|
||||
|
||||
func newSpecReport(in types.SpecReport) *gojsonSpecReport {
|
||||
return &gojsonSpecReport{
|
||||
o: in,
|
||||
}
|
||||
}
|
||||
|
||||
func (sr *gojsonSpecReport) Fill() error {
|
||||
sr.elapsed = sr.o.RunTime.Seconds()
|
||||
sr.testName = createTestName(sr.o)
|
||||
sr.action = goJSONActionFromSpecState(sr.o.State)
|
||||
return nil
|
||||
}
|
||||
|
||||
func suitePathToPkg(dir string) (string, error) {
|
||||
cfg := &packages.Config{
|
||||
Mode: packages.NeedFiles | packages.NeedSyntax,
|
||||
}
|
||||
pkgs, err := packages.Load(cfg, dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(pkgs) != 1 {
|
||||
return "", errors.New("error")
|
||||
}
|
||||
return pkgs[0].ID, nil
|
||||
}
|
||||
|
||||
func createTestName(spec types.SpecReport) string {
|
||||
name := fmt.Sprintf("[%s]", spec.LeafNodeType)
|
||||
if spec.FullText() != "" {
|
||||
name = name + " " + spec.FullText()
|
||||
}
|
||||
labels := spec.Labels()
|
||||
if len(labels) > 0 {
|
||||
name = name + " [" + strings.Join(labels, ", ") + "]"
|
||||
}
|
||||
semVerConstraints := spec.SemVerConstraints()
|
||||
if len(semVerConstraints) > 0 {
|
||||
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
|
||||
}
|
||||
name = strings.TrimSpace(name)
|
||||
return name
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
package reporters
|
||||
|
||||
type GoJSONEventWriter struct {
|
||||
enc encoder
|
||||
specSystemErrFn specSystemExtractFn
|
||||
specSystemOutFn specSystemExtractFn
|
||||
}
|
||||
|
||||
func NewGoJSONEventWriter(enc encoder, errFn specSystemExtractFn, outFn specSystemExtractFn) *GoJSONEventWriter {
|
||||
return &GoJSONEventWriter{
|
||||
enc: enc,
|
||||
specSystemErrFn: errFn,
|
||||
specSystemOutFn: outFn,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) writeEvent(e *gojsonEvent) error {
|
||||
return r.enc.Encode(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSuiteStart(report *gojsonReport) error {
|
||||
e := &gojsonEvent{
|
||||
Time: &report.o.StartTime,
|
||||
Action: GoJSONStart,
|
||||
Package: report.goPkg,
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSuiteResult(report *gojsonReport) error {
|
||||
var action GoJSONAction
|
||||
switch {
|
||||
case report.o.PreRunStats.SpecsThatWillRun == 0:
|
||||
action = GoJSONSkip
|
||||
case report.o.SuiteSucceeded:
|
||||
action = GoJSONPass
|
||||
default:
|
||||
action = GoJSONFail
|
||||
}
|
||||
e := &gojsonEvent{
|
||||
Time: &report.o.EndTime,
|
||||
Action: action,
|
||||
Package: report.goPkg,
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
Elapsed: ptr(report.elapsed),
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSpecStart(report *gojsonReport, specReport *gojsonSpecReport) error {
|
||||
e := &gojsonEvent{
|
||||
Time: &specReport.o.StartTime,
|
||||
Action: GoJSONRun,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSpecOut(report *gojsonReport, specReport *gojsonSpecReport) error {
|
||||
events := []*gojsonEvent{}
|
||||
|
||||
stdErr := r.specSystemErrFn(specReport.o)
|
||||
if stdErr != "" {
|
||||
events = append(events, &gojsonEvent{
|
||||
Time: &specReport.o.EndTime,
|
||||
Action: GoJSONOutput,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Output: ptr(stdErr),
|
||||
FailedBuild: "",
|
||||
})
|
||||
}
|
||||
stdOut := r.specSystemOutFn(specReport.o)
|
||||
if stdOut != "" {
|
||||
events = append(events, &gojsonEvent{
|
||||
Time: &specReport.o.EndTime,
|
||||
Action: GoJSONOutput,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Output: ptr(stdOut),
|
||||
FailedBuild: "",
|
||||
})
|
||||
}
|
||||
|
||||
for _, ev := range events {
|
||||
err := r.writeEvent(ev)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *GoJSONEventWriter) WriteSpecResult(report *gojsonReport, specReport *gojsonSpecReport) error {
|
||||
e := &gojsonEvent{
|
||||
Time: &specReport.o.EndTime,
|
||||
Action: specReport.action,
|
||||
Test: specReport.testName,
|
||||
Package: report.goPkg,
|
||||
Elapsed: ptr(specReport.elapsed),
|
||||
Output: nil,
|
||||
FailedBuild: "",
|
||||
}
|
||||
return r.writeEvent(e)
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package reporters
|
||||
|
||||
import (
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
)
|
||||
|
||||
type GoJSONReporter struct {
|
||||
ev *GoJSONEventWriter
|
||||
}
|
||||
|
||||
type specSystemExtractFn func (spec types.SpecReport) string
|
||||
|
||||
func NewGoJSONReporter(enc encoder, errFn specSystemExtractFn, outFn specSystemExtractFn) *GoJSONReporter {
|
||||
return &GoJSONReporter{
|
||||
ev: NewGoJSONEventWriter(enc, errFn, outFn),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *GoJSONReporter) Write(originalReport types.Report) error {
|
||||
// suite start events
|
||||
report := newReport(originalReport)
|
||||
err := report.Fill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.ev.WriteSuiteStart(report)
|
||||
for _, originalSpecReport := range originalReport.SpecReports {
|
||||
specReport := newSpecReport(originalSpecReport)
|
||||
err := specReport.Fill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if specReport.o.LeafNodeType == types.NodeTypeIt {
|
||||
// handle any It leaf node as a spec
|
||||
r.ev.WriteSpecStart(report, specReport)
|
||||
r.ev.WriteSpecOut(report, specReport)
|
||||
r.ev.WriteSpecResult(report, specReport)
|
||||
} else {
|
||||
// handle any other leaf node as generic output
|
||||
r.ev.WriteSpecOut(report, specReport)
|
||||
}
|
||||
}
|
||||
r.ev.WriteSuiteResult(report)
|
||||
return nil
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package reporters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/onsi/ginkgo/v2/internal/reporters"
|
||||
"github.com/onsi/ginkgo/v2/types"
|
||||
)
|
||||
|
||||
// GenerateGoTestJSONReport produces a JSON-formatted in the test2json format used by `go test -json`
|
||||
func GenerateGoTestJSONReport(report types.Report, destination string) error {
|
||||
// walk report and generate test2json-compatible objects
|
||||
// JSON-encode the objects into filename
|
||||
if err := os.MkdirAll(path.Dir(destination), 0770); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
enc := json.NewEncoder(f)
|
||||
r := reporters.NewGoJSONReporter(
|
||||
enc,
|
||||
systemErrForUnstructuredReporters,
|
||||
systemOutForUnstructuredReporters,
|
||||
)
|
||||
return r.Write(report)
|
||||
}
|
||||
|
||||
// MergeJSONReports produces a single JSON-formatted report at the passed in destination by merging the JSON-formatted reports provided in sources
|
||||
// It skips over reports that fail to decode but reports on them via the returned messages []string
|
||||
func MergeAndCleanupGoTestJSONReports(sources []string, destination string) ([]string, error) {
|
||||
messages := []string{}
|
||||
if err := os.MkdirAll(path.Dir(destination), 0770); err != nil {
|
||||
return messages, err
|
||||
}
|
||||
f, err := os.Create(destination)
|
||||
if err != nil {
|
||||
return messages, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for _, source := range sources {
|
||||
data, err := os.ReadFile(source)
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("Could not open %s:\n%s", source, err.Error()))
|
||||
continue
|
||||
}
|
||||
_, err = f.Write(data)
|
||||
if err != nil {
|
||||
messages = append(messages, fmt.Sprintf("Could not write to %s:\n%s", destination, err.Error()))
|
||||
continue
|
||||
}
|
||||
os.Remove(source)
|
||||
}
|
||||
return messages, nil
|
||||
}
|
||||
+10
-1
@@ -165,7 +165,7 @@ ReportAfterSuite nodes must be created at the top-level (i.e. not nested in a Co
|
||||
When running in parallel, Ginkgo ensures that only one of the parallel nodes runs the ReportAfterSuite and that it is passed a report that is aggregated across
|
||||
all parallel nodes
|
||||
|
||||
In addition to using ReportAfterSuite to programmatically generate suite reports, you can also generate JSON, JUnit, and Teamcity formatted reports using the --json-report, --junit-report, and --teamcity-report ginkgo CLI flags.
|
||||
In addition to using ReportAfterSuite to programmatically generate suite reports, you can also generate JSON, GoJSON, JUnit, and Teamcity formatted reports using the --json-report, --gojson-report, --junit-report, and --teamcity-report ginkgo CLI flags.
|
||||
|
||||
You cannot nest any other Ginkgo nodes within a ReportAfterSuite node's closure.
|
||||
You can learn more about ReportAfterSuite here: https://onsi.github.io/ginkgo/#generating-reports-programmatically
|
||||
@@ -188,6 +188,12 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
|
||||
Fail(fmt.Sprintf("Failed to generate JSON report:\n%s", err.Error()))
|
||||
}
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
err := reporters.GenerateGoTestJSONReport(report, reporterConfig.GoJSONReport)
|
||||
if err != nil {
|
||||
Fail(fmt.Sprintf("Failed to generate Go JSON report:\n%s", err.Error()))
|
||||
}
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
err := reporters.GenerateJUnitReport(report, reporterConfig.JUnitReport)
|
||||
if err != nil {
|
||||
@@ -206,6 +212,9 @@ func registerReportAfterSuiteNodeForAutogeneratedReports(reporterConfig types.Re
|
||||
if reporterConfig.JSONReport != "" {
|
||||
flags = append(flags, "--json-report")
|
||||
}
|
||||
if reporterConfig.GoJSONReport != "" {
|
||||
flags = append(flags, "--gojson-report")
|
||||
}
|
||||
if reporterConfig.JUnitReport != "" {
|
||||
flags = append(flags, "--junit-report")
|
||||
}
|
||||
|
||||
+4
-1
@@ -96,6 +96,7 @@ type ReporterConfig struct {
|
||||
ForceNewlines bool
|
||||
|
||||
JSONReport string
|
||||
GoJSONReport string
|
||||
JUnitReport string
|
||||
TeamcityReport string
|
||||
}
|
||||
@@ -112,7 +113,7 @@ func (rc ReporterConfig) Verbosity() VerbosityLevel {
|
||||
}
|
||||
|
||||
func (rc ReporterConfig) WillGenerateReport() bool {
|
||||
return rc.JSONReport != "" || rc.JUnitReport != "" || rc.TeamcityReport != ""
|
||||
return rc.JSONReport != "" || rc.GoJSONReport != "" || rc.JUnitReport != "" || rc.TeamcityReport != ""
|
||||
}
|
||||
|
||||
func NewDefaultReporterConfig() ReporterConfig {
|
||||
@@ -359,6 +360,8 @@ var ReporterConfigFlags = GinkgoFlags{
|
||||
|
||||
{KeyPath: "R.JSONReport", Name: "json-report", UsageArgument: "filename.json", SectionKey: "output",
|
||||
Usage: "If set, Ginkgo will generate a JSON-formatted test report at the specified location."},
|
||||
{KeyPath: "R.GoJSONReport", Name: "gojson-report", UsageArgument: "filename.json", SectionKey: "output",
|
||||
Usage: "If set, Ginkgo will generate a Go JSON-formatted test report at the specified location."},
|
||||
{KeyPath: "R.JUnitReport", Name: "junit-report", UsageArgument: "filename.xml", SectionKey: "output", DeprecatedName: "reportFile", DeprecatedDocLink: "improved-reporting-infrastructure",
|
||||
Usage: "If set, Ginkgo will generate a conformant junit test report in the specified file."},
|
||||
{KeyPath: "R.TeamcityReport", Name: "teamcity-report", UsageArgument: "filename", SectionKey: "output",
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package types
|
||||
|
||||
const VERSION = "2.25.3"
|
||||
const VERSION = "2.26.0"
|
||||
|
||||
Reference in New Issue
Block a user