reva-bump-2.42.2
This commit is contained in:
committed by
Ralf Haferkamp
parent
f21207ed96
commit
2bf70a6f70
+18
@@ -1,3 +1,21 @@
|
||||
## 2.28.0
|
||||
|
||||
Ginkgo's SemVer filter now supports filtering multiple components by SemVer version:
|
||||
|
||||
```go
|
||||
It("should work in a specific version range (1.0.0, 2.0.0) and third-party dependency redis in [8.0.0, ~)", SemVerConstraint(">= 3.2.0"), ComponentSemVerConstraint("redis", ">= 8.0.0") func() {
|
||||
// This test will only run when version is between 1.0.0 (exclusive) and 2.0.0 (exclusive) and redis version is >= 8.0.0
|
||||
})
|
||||
```
|
||||
|
||||
can be filtered in or out with an invocation like:
|
||||
|
||||
```bash
|
||||
ginkgo --sem-ver-filter="2.1.1, redis=8.2.0"
|
||||
```
|
||||
|
||||
Huge thanks to @Icarus9913 for working on this!
|
||||
|
||||
## 2.27.5
|
||||
|
||||
### Fixes
|
||||
|
||||
+13
-6
@@ -20,6 +20,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
@@ -268,7 +269,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
|
||||
}
|
||||
defer global.PopClone()
|
||||
|
||||
suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
|
||||
suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
|
||||
|
||||
var reporter reporters.Reporter
|
||||
if suiteConfig.ParallelTotal == 1 {
|
||||
@@ -311,7 +312,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
|
||||
suitePath, err = filepath.Abs(suitePath)
|
||||
exitIfErr(err)
|
||||
|
||||
passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
|
||||
passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
|
||||
outputInterceptor.Shutdown()
|
||||
|
||||
flagSet.ValidateDeprecations(deprecationTracker)
|
||||
@@ -330,9 +331,10 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
|
||||
return passed
|
||||
}
|
||||
|
||||
func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.AroundNodes) {
|
||||
func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, ComponentSemVerConstraints, types.AroundNodes) {
|
||||
suiteLabels := Labels{}
|
||||
suiteSemVerConstraints := SemVerConstraints{}
|
||||
suiteComponentSemVerConstraints := ComponentSemVerConstraints{}
|
||||
aroundNodes := types.AroundNodes{}
|
||||
configErrors := []error{}
|
||||
for _, arg := range args {
|
||||
@@ -345,6 +347,11 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro
|
||||
suiteLabels = append(suiteLabels, arg...)
|
||||
case SemVerConstraints:
|
||||
suiteSemVerConstraints = append(suiteSemVerConstraints, arg...)
|
||||
case ComponentSemVerConstraints:
|
||||
for component, constraints := range arg {
|
||||
suiteComponentSemVerConstraints[component] = append(suiteComponentSemVerConstraints[component], constraints...)
|
||||
suiteComponentSemVerConstraints[component] = slices.Compact(suiteComponentSemVerConstraints[component])
|
||||
}
|
||||
case types.AroundNodeDecorator:
|
||||
aroundNodes = append(aroundNodes, arg)
|
||||
default:
|
||||
@@ -362,7 +369,7 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.Aro
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return suiteLabels, suiteSemVerConstraints, aroundNodes
|
||||
return suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, aroundNodes
|
||||
}
|
||||
|
||||
func getwd() (string, error) {
|
||||
@@ -385,7 +392,7 @@ func PreviewSpecs(description string, args ...any) Report {
|
||||
}
|
||||
defer global.PopClone()
|
||||
|
||||
suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
|
||||
suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
|
||||
priorDryRun, priorParallelTotal, priorParallelProcess := suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess
|
||||
suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess = true, 1, 1
|
||||
defer func() {
|
||||
@@ -403,7 +410,7 @@ func PreviewSpecs(description string, args ...any) Report {
|
||||
suitePath, err = filepath.Abs(suitePath)
|
||||
exitIfErr(err)
|
||||
|
||||
global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
|
||||
global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
|
||||
|
||||
return global.Suite.GetPreviewReport()
|
||||
}
|
||||
|
||||
+21
@@ -117,6 +117,27 @@ You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-fi
|
||||
*/
|
||||
type SemVerConstraints = internal.SemVerConstraints
|
||||
|
||||
/*
|
||||
ComponentSemVerConstraint decorates specs with ComponentSemVerConstraints. Multiple components semantic version constraints can be passed to ComponentSemVerConstraint and the component can't be empy, also the version strings must follow the semantic version constraint rules.
|
||||
ComponentSemVerConstraints can be applied to container and subject nodes, but not setup nodes. You can provide multiple ComponentSemVerConstraints to a given node and a spec's component semantic version constraints is the union of all component semantic version constraints in its node hierarchy.
|
||||
|
||||
You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
|
||||
You can learn more about decorators here: https://onsi.github.io/ginkgo/#decorator-reference
|
||||
*/
|
||||
func ComponentSemVerConstraint(component string, semVerConstraints ...string) ComponentSemVerConstraints {
|
||||
componentSemVerConstraints := ComponentSemVerConstraints{
|
||||
component: semVerConstraints,
|
||||
}
|
||||
|
||||
return componentSemVerConstraints
|
||||
}
|
||||
|
||||
/*
|
||||
ComponentSemVerConstraints are the type for spec ComponentSemVerConstraint decorators. Use ComponentSemVerConstraint(...) to construct ComponentSemVerConstraints.
|
||||
You can learn more here: https://onsi.github.io/ginkgo/#spec-semantic-version-filtering
|
||||
*/
|
||||
type ComponentSemVerConstraints = internal.ComponentSemVerConstraints
|
||||
|
||||
/*
|
||||
PollProgressAfter allows you to override the configured value for --poll-progress-after for a particular node.
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ func BuildRunCommand() command.Command {
|
||||
Usage: "ginkgo run <FLAGS> <PACKAGES> -- <PASS-THROUGHS>",
|
||||
ShortDoc: "Run the tests in the passed in <PACKAGES> (or the package in the current directory if left blank)",
|
||||
Documentation: "Any arguments after -- will be passed to the test.",
|
||||
DocLink: "running-tests",
|
||||
DocLink: "running-specs",
|
||||
Command: func(args []string, additionalArgs []string) {
|
||||
var errors []error
|
||||
cliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)
|
||||
|
||||
+19
-2
@@ -56,7 +56,7 @@ This function sets the `Skip` property on specs by applying Ginkgo's focus polic
|
||||
|
||||
*Note:* specs with pending nodes are Skipped when created by NewSpec.
|
||||
*/
|
||||
func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) {
|
||||
func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteConfig types.SuiteConfig) (Specs, bool) {
|
||||
focusString := strings.Join(suiteConfig.FocusStrings, "|")
|
||||
skipString := strings.Join(suiteConfig.SkipStrings, "|")
|
||||
|
||||
@@ -87,7 +87,24 @@ func ApplyFocusToSpecs(specs Specs, description string, suiteLabels Labels, suit
|
||||
if suiteConfig.SemVerFilter != "" {
|
||||
semVerFilter, _ := types.ParseSemVerFilter(suiteConfig.SemVerFilter)
|
||||
skipChecks = append(skipChecks, func(spec Spec) bool {
|
||||
return !semVerFilter(UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints()))
|
||||
noRun := false
|
||||
|
||||
// non-component-specific constraints
|
||||
constraints := UnionOfSemVerConstraints(suiteSemVerConstraints, spec.Nodes.UnionOfSemVerConstraints())
|
||||
if len(constraints) != 0 && semVerFilter("", constraints) == false {
|
||||
noRun = true
|
||||
}
|
||||
|
||||
// component-specific constraints
|
||||
componentConstraints := UnionOfComponentSemVerConstraints(suiteComponentSemVerConstraints, spec.Nodes.UnionOfComponentSemVerConstraints())
|
||||
for component, constraints := range componentConstraints {
|
||||
if semVerFilter(component, constraints) == false {
|
||||
noRun = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return noRun
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+19
-16
@@ -113,22 +113,24 @@ func newGroup(suite *Suite) *group {
|
||||
// initialReportForSpec constructs a new SpecReport right before running the spec.
|
||||
func (g *group) initialReportForSpec(spec Spec) types.SpecReport {
|
||||
return types.SpecReport{
|
||||
ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(),
|
||||
ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(),
|
||||
ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(),
|
||||
ContainerHierarchySemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).SemVerConstraints(),
|
||||
LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation,
|
||||
LeafNodeType: types.NodeTypeIt,
|
||||
LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text,
|
||||
LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels),
|
||||
LeafNodeSemVerConstraints: []string(spec.FirstNodeWithType(types.NodeTypeIt).SemVerConstraints),
|
||||
ParallelProcess: g.suite.config.ParallelProcess,
|
||||
RunningInParallel: g.suite.isRunningInParallel(),
|
||||
IsSerial: spec.Nodes.HasNodeMarkedSerial(),
|
||||
IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
|
||||
MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(),
|
||||
MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(),
|
||||
SpecPriority: spec.Nodes.GetSpecPriority(),
|
||||
ContainerHierarchyTexts: spec.Nodes.WithType(types.NodeTypeContainer).Texts(),
|
||||
ContainerHierarchyLocations: spec.Nodes.WithType(types.NodeTypeContainer).CodeLocations(),
|
||||
ContainerHierarchyLabels: spec.Nodes.WithType(types.NodeTypeContainer).Labels(),
|
||||
ContainerHierarchySemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).SemVerConstraints(),
|
||||
ContainerHierarchyComponentSemVerConstraints: spec.Nodes.WithType(types.NodeTypeContainer).ComponentSemVerConstraints(),
|
||||
LeafNodeLocation: spec.FirstNodeWithType(types.NodeTypeIt).CodeLocation,
|
||||
LeafNodeType: types.NodeTypeIt,
|
||||
LeafNodeText: spec.FirstNodeWithType(types.NodeTypeIt).Text,
|
||||
LeafNodeLabels: []string(spec.FirstNodeWithType(types.NodeTypeIt).Labels),
|
||||
LeafNodeSemVerConstraints: []string(spec.FirstNodeWithType(types.NodeTypeIt).SemVerConstraints),
|
||||
LeafNodeComponentSemVerConstraints: map[string][]string(spec.FirstNodeWithType(types.NodeTypeIt).ComponentSemVerConstraints),
|
||||
ParallelProcess: g.suite.config.ParallelProcess,
|
||||
RunningInParallel: g.suite.isRunningInParallel(),
|
||||
IsSerial: spec.Nodes.HasNodeMarkedSerial(),
|
||||
IsInOrderedContainer: !spec.Nodes.FirstNodeMarkedOrdered().IsZero(),
|
||||
MaxFlakeAttempts: spec.Nodes.GetMaxFlakeAttempts(),
|
||||
MaxMustPassRepeatedly: spec.Nodes.GetMaxMustPassRepeatedly(),
|
||||
SpecPriority: spec.Nodes.GetSpecPriority(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +154,7 @@ func addNodeToReportForNode(report *types.ConstructionNodeReport, node *TreeNode
|
||||
report.ContainerHierarchyLocations = append(report.ContainerHierarchyLocations, node.Node.CodeLocation)
|
||||
report.ContainerHierarchyLabels = append(report.ContainerHierarchyLabels, node.Node.Labels)
|
||||
report.ContainerHierarchySemVerConstraints = append(report.ContainerHierarchySemVerConstraints, node.Node.SemVerConstraints)
|
||||
report.ContainerHierarchyComponentSemVerConstraints = append(report.ContainerHierarchyComponentSemVerConstraints, node.Node.ComponentSemVerConstraints)
|
||||
if node.Node.MarkedSerial {
|
||||
report.IsSerial = true
|
||||
}
|
||||
|
||||
+100
-11
@@ -57,6 +57,7 @@ type Node struct {
|
||||
MustPassRepeatedly int
|
||||
Labels Labels
|
||||
SemVerConstraints SemVerConstraints
|
||||
ComponentSemVerConstraints ComponentSemVerConstraints
|
||||
PollProgressAfter time.Duration
|
||||
PollProgressInterval time.Duration
|
||||
NodeTimeout time.Duration
|
||||
@@ -106,7 +107,24 @@ func (l Labels) MatchesLabelFilter(query string) bool {
|
||||
type SemVerConstraints []string
|
||||
|
||||
func (svc SemVerConstraints) MatchesSemVerFilter(version string) bool {
|
||||
return types.MustParseSemVerFilter(version)(svc)
|
||||
return types.MustParseSemVerFilter(version)("", svc)
|
||||
}
|
||||
|
||||
type ComponentSemVerConstraints map[string][]string
|
||||
|
||||
func (csvc ComponentSemVerConstraints) MatchesSemVerFilter(component, version string) bool {
|
||||
for comp, constraints := range csvc {
|
||||
if comp != component {
|
||||
continue
|
||||
}
|
||||
|
||||
input := version
|
||||
if len(component) > 0 {
|
||||
input = fmt.Sprintf("%s=%s", component, version)
|
||||
}
|
||||
return types.MustParseSemVerFilter(input)(component, constraints)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func unionOf[S ~[]E, E comparable](slices ...S) S {
|
||||
@@ -131,6 +149,16 @@ func UnionOfSemVerConstraints(semVerConstraints ...SemVerConstraints) SemVerCons
|
||||
return unionOf(semVerConstraints...)
|
||||
}
|
||||
|
||||
func UnionOfComponentSemVerConstraints(componentSemVerConstraintsSlice ...ComponentSemVerConstraints) ComponentSemVerConstraints {
|
||||
unionComponentSemVerConstraints := ComponentSemVerConstraints{}
|
||||
for _, componentSemVerConstraints := range componentSemVerConstraintsSlice {
|
||||
for component, constraints := range componentSemVerConstraints {
|
||||
unionComponentSemVerConstraints[component] = unionOf(unionComponentSemVerConstraints[component], constraints)
|
||||
}
|
||||
}
|
||||
return unionComponentSemVerConstraints
|
||||
}
|
||||
|
||||
func PartitionDecorations(args ...any) ([]any, []any) {
|
||||
decorations := []any{}
|
||||
remainingArgs := []any{}
|
||||
@@ -174,6 +202,8 @@ func isDecoration(arg any) bool {
|
||||
return true
|
||||
case t == reflect.TypeOf(SemVerConstraints{}):
|
||||
return true
|
||||
case t == reflect.TypeOf(ComponentSemVerConstraints{}):
|
||||
return true
|
||||
case t == reflect.TypeOf(PollProgressInterval(0)):
|
||||
return true
|
||||
case t == reflect.TypeOf(PollProgressAfter(0)):
|
||||
@@ -214,16 +244,17 @@ var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
|
||||
func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeType, text string, args ...any) (Node, []error) {
|
||||
baseOffset := 2
|
||||
node := Node{
|
||||
ID: UniqueNodeID(),
|
||||
NodeType: nodeType,
|
||||
Text: text,
|
||||
Labels: Labels{},
|
||||
SemVerConstraints: SemVerConstraints{},
|
||||
CodeLocation: types.NewCodeLocation(baseOffset),
|
||||
NestingLevel: -1,
|
||||
PollProgressAfter: -1,
|
||||
PollProgressInterval: -1,
|
||||
GracePeriod: -1,
|
||||
ID: UniqueNodeID(),
|
||||
NodeType: nodeType,
|
||||
Text: text,
|
||||
Labels: Labels{},
|
||||
SemVerConstraints: SemVerConstraints{},
|
||||
ComponentSemVerConstraints: ComponentSemVerConstraints{},
|
||||
CodeLocation: types.NewCodeLocation(baseOffset),
|
||||
NestingLevel: -1,
|
||||
PollProgressAfter: -1,
|
||||
PollProgressInterval: -1,
|
||||
GracePeriod: -1,
|
||||
}
|
||||
|
||||
errors := []error{}
|
||||
@@ -360,6 +391,36 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
|
||||
appendError(err)
|
||||
}
|
||||
}
|
||||
case t == reflect.TypeOf(ComponentSemVerConstraints{}):
|
||||
if !nodeType.Is(types.NodeTypesForContainerAndIt) {
|
||||
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "ComponentSemVerConstraint"))
|
||||
}
|
||||
for component, semVerConstraints := range arg.(ComponentSemVerConstraints) {
|
||||
// while using ComponentSemVerConstraints, we should not allow empty component names.
|
||||
// you should use SemVerConstraints for that.
|
||||
hasErr := false
|
||||
if len(component) == 0 {
|
||||
appendError(types.GinkgoErrors.InvalidEmptyComponentForSemVerConstraint(node.CodeLocation))
|
||||
hasErr = true
|
||||
}
|
||||
for _, semVerConstraint := range semVerConstraints {
|
||||
_, err := types.ValidateAndCleanupSemVerConstraint(semVerConstraint, node.CodeLocation)
|
||||
if err != nil {
|
||||
appendError(err)
|
||||
hasErr = true
|
||||
}
|
||||
}
|
||||
|
||||
if !hasErr {
|
||||
// merge constraints if the component already exists
|
||||
constraints := slices.Clone(semVerConstraints)
|
||||
if existingConstraints, exists := node.ComponentSemVerConstraints[component]; exists {
|
||||
constraints = UnionOfSemVerConstraints([]string(existingConstraints), constraints)
|
||||
}
|
||||
|
||||
node.ComponentSemVerConstraints[component] = slices.Clone(constraints)
|
||||
}
|
||||
}
|
||||
case t.Kind() == reflect.Func:
|
||||
if nodeType.Is(types.NodeTypeContainer) {
|
||||
if node.Body != nil {
|
||||
@@ -899,6 +960,34 @@ func (n Nodes) UnionOfSemVerConstraints() []string {
|
||||
return out
|
||||
}
|
||||
|
||||
func (n Nodes) ComponentSemVerConstraints() []map[string][]string {
|
||||
out := make([]map[string][]string, len(n))
|
||||
for i := range n {
|
||||
if n[i].ComponentSemVerConstraints == nil {
|
||||
out[i] = map[string][]string{}
|
||||
} else {
|
||||
out[i] = map[string][]string(n[i].ComponentSemVerConstraints)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (n Nodes) UnionOfComponentSemVerConstraints() map[string][]string {
|
||||
out := map[string][]string{}
|
||||
seen := map[string]bool{}
|
||||
for i := range n {
|
||||
for component := range n[i].ComponentSemVerConstraints {
|
||||
if !seen[component] {
|
||||
seen[component] = true
|
||||
out[component] = n[i].ComponentSemVerConstraints[component]
|
||||
} else {
|
||||
out[component] = UnionOfSemVerConstraints(out[component], n[i].ComponentSemVerConstraints[component])
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (n Nodes) CodeLocations() []types.CodeLocation {
|
||||
out := make([]types.CodeLocation, len(n))
|
||||
for i := range n {
|
||||
|
||||
+30
-17
@@ -83,7 +83,7 @@ func goJSONActionFromSpecState(state types.SpecState) GoJSONAction {
|
||||
type gojsonReport struct {
|
||||
o types.Report
|
||||
// Extra calculated fields
|
||||
goPkg string
|
||||
goPkg string
|
||||
elapsed float64
|
||||
}
|
||||
|
||||
@@ -109,8 +109,8 @@ type gojsonSpecReport struct {
|
||||
o types.SpecReport
|
||||
// extra calculated fields
|
||||
testName string
|
||||
elapsed float64
|
||||
action GoJSONAction
|
||||
elapsed float64
|
||||
action GoJSONAction
|
||||
}
|
||||
|
||||
func newSpecReport(in types.SpecReport) *gojsonSpecReport {
|
||||
@@ -141,18 +141,31 @@ func suitePathToPkg(dir string) (string, error) {
|
||||
}
|
||||
|
||||
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
|
||||
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, ", ") + "]"
|
||||
}
|
||||
componentSemVerConstraints := spec.ComponentSemVerConstraints()
|
||||
if len(componentSemVerConstraints) > 0 {
|
||||
name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
|
||||
}
|
||||
name = strings.TrimSpace(name)
|
||||
return name
|
||||
}
|
||||
|
||||
func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string {
|
||||
var tmpStr string
|
||||
for component, semVerConstraints := range componentSemVerConstraints {
|
||||
tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", component, semVerConstraints)
|
||||
}
|
||||
tmpStr = strings.TrimSuffix(tmpStr, ", ")
|
||||
return tmpStr
|
||||
}
|
||||
|
||||
+11
-10
@@ -108,13 +108,13 @@ func (suite *Suite) BuildTree() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) {
|
||||
func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) {
|
||||
if suite.phase != PhaseBuildTree {
|
||||
panic("cannot run before building the tree = call suite.BuildTree() first")
|
||||
}
|
||||
ApplyNestedFocusPolicyToTree(suite.tree)
|
||||
specs := GenerateSpecsFromTreeRoot(suite.tree)
|
||||
specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteConfig)
|
||||
specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suiteConfig)
|
||||
specs = ComputeAroundNodes(specs)
|
||||
|
||||
suite.phase = PhaseRun
|
||||
@@ -133,7 +133,7 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst
|
||||
|
||||
cancelProgressHandler := progressSignalRegistrar(suite.handleProgressSignal)
|
||||
|
||||
success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suitePath, hasProgrammaticFocus, specs)
|
||||
success := suite.runSpecs(description, suiteLabels, suiteSemVerConstraints, suiteComponentSemVerConstraints, suitePath, hasProgrammaticFocus, specs)
|
||||
|
||||
cancelProgressHandler()
|
||||
|
||||
@@ -456,16 +456,17 @@ func (suite *Suite) processCurrentSpecReport() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
|
||||
func (suite *Suite) runSpecs(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteComponentSemVerConstraints ComponentSemVerConstraints, suitePath string, hasProgrammaticFocus bool, specs Specs) bool {
|
||||
numSpecsThatWillBeRun := specs.CountWithoutSkip()
|
||||
|
||||
suite.report = types.Report{
|
||||
SuitePath: suitePath,
|
||||
SuiteDescription: description,
|
||||
SuiteLabels: suiteLabels,
|
||||
SuiteSemVerConstraints: suiteSemVerConstraints,
|
||||
SuiteConfig: suite.config,
|
||||
SuiteHasProgrammaticFocus: hasProgrammaticFocus,
|
||||
SuitePath: suitePath,
|
||||
SuiteDescription: description,
|
||||
SuiteLabels: suiteLabels,
|
||||
SuiteSemVerConstraints: suiteSemVerConstraints,
|
||||
SuiteComponentSemVerConstraints: suiteComponentSemVerConstraints,
|
||||
SuiteConfig: suite.config,
|
||||
SuiteHasProgrammaticFocus: hasProgrammaticFocus,
|
||||
PreRunStats: types.PreRunStats{
|
||||
TotalSpecs: len(specs),
|
||||
SpecsThatWillRun: numSpecsThatWillBeRun,
|
||||
|
||||
+25
-2
@@ -75,6 +75,9 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
|
||||
if len(report.SuiteSemVerConstraints) > 0 {
|
||||
r.emit(r.f("{{coral}}[%s]{{/}} ", strings.Join(report.SuiteSemVerConstraints, ", ")))
|
||||
}
|
||||
if len(report.SuiteComponentSemVerConstraints) > 0 {
|
||||
r.emit(r.f("{{coral}}[Components: %s]{{/}} ", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints)))
|
||||
}
|
||||
r.emit(r.f("- %d/%d specs ", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs))
|
||||
if report.SuiteConfig.ParallelTotal > 1 {
|
||||
r.emit(r.f("- %d procs ", report.SuiteConfig.ParallelTotal))
|
||||
@@ -97,6 +100,13 @@ func (r *DefaultReporter) SuiteWillBegin(report types.Report) {
|
||||
bannerWidth = len(semVerConstraints) + 2
|
||||
}
|
||||
}
|
||||
if len(report.SuiteComponentSemVerConstraints) > 0 {
|
||||
componentSemVerConstraints := formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints)
|
||||
r.emitBlock(r.f("{{coral}}[Components: %s]{{/}} ", componentSemVerConstraints))
|
||||
if len(componentSemVerConstraints)+2 > bannerWidth {
|
||||
bannerWidth = len(componentSemVerConstraints) + 2
|
||||
}
|
||||
}
|
||||
r.emitBlock(strings.Repeat("=", bannerWidth))
|
||||
|
||||
out := r.f("Random Seed: {{bold}}%d{{/}}", report.SuiteConfig.RandomSeed)
|
||||
@@ -725,8 +735,12 @@ func (r *DefaultReporter) cycleJoin(elements []string, joiner string) string {
|
||||
}
|
||||
|
||||
func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string {
|
||||
texts, locations, labels, semVerConstraints := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{}
|
||||
texts, locations, labels, semVerConstraints = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...), append(semVerConstraints, report.ContainerHierarchySemVerConstraints...)
|
||||
texts, locations, labels, semVerConstraints, componentSemVerConstraints := []string{}, []types.CodeLocation{}, [][]string{}, [][]string{}, []map[string][]string{}
|
||||
texts = append(texts, report.ContainerHierarchyTexts...)
|
||||
locations = append(locations, report.ContainerHierarchyLocations...)
|
||||
labels = append(labels, report.ContainerHierarchyLabels...)
|
||||
semVerConstraints = append(semVerConstraints, report.ContainerHierarchySemVerConstraints...)
|
||||
componentSemVerConstraints = append(componentSemVerConstraints, report.ContainerHierarchyComponentSemVerConstraints...)
|
||||
|
||||
if report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {
|
||||
texts = append(texts, r.f("[%s] %s", report.LeafNodeType, report.LeafNodeText))
|
||||
@@ -735,6 +749,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
|
||||
}
|
||||
labels = append(labels, report.LeafNodeLabels)
|
||||
semVerConstraints = append(semVerConstraints, report.LeafNodeSemVerConstraints)
|
||||
componentSemVerConstraints = append(componentSemVerConstraints, report.LeafNodeComponentSemVerConstraints)
|
||||
locations = append(locations, report.LeafNodeLocation)
|
||||
|
||||
failureLocation := report.Failure.FailureNodeLocation
|
||||
@@ -749,6 +764,7 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
|
||||
locations = append([]types.CodeLocation{failureLocation}, locations...)
|
||||
labels = append([][]string{{}}, labels...)
|
||||
semVerConstraints = append([][]string{{}}, semVerConstraints...)
|
||||
componentSemVerConstraints = append([]map[string][]string{{}}, componentSemVerConstraints...)
|
||||
highlightIndex = 0
|
||||
case types.FailureNodeInContainer:
|
||||
i := report.Failure.FailureNodeContainerIndex
|
||||
@@ -779,6 +795,9 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
|
||||
if len(semVerConstraints[i]) > 0 {
|
||||
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(semVerConstraints[i], ", "))
|
||||
}
|
||||
if len(componentSemVerConstraints[i]) > 0 {
|
||||
out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(componentSemVerConstraints[i]))
|
||||
}
|
||||
out += "\n"
|
||||
out += r.fi(uint(i), "{{gray}}%s{{/}}\n", locations[i])
|
||||
}
|
||||
@@ -806,6 +825,10 @@ func (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightCo
|
||||
if len(flattenedSemVerConstraints) > 0 {
|
||||
out += r.f(" {{coral}}[%s]{{/}}", strings.Join(flattenedSemVerConstraints, ", "))
|
||||
}
|
||||
flattenedComponentSemVerConstraints := report.ComponentSemVerConstraints()
|
||||
if len(flattenedComponentSemVerConstraints) > 0 {
|
||||
out += r.f(" {{coral}}[%s]{{/}}", formatComponentSemVerConstraintsToString(flattenedComponentSemVerConstraints))
|
||||
}
|
||||
out += "\n"
|
||||
if usePreciseFailureLocation {
|
||||
out += r.f("{{gray}}%s{{/}}", failureLocation)
|
||||
|
||||
+20
@@ -13,9 +13,11 @@ package reporters
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo/v2/config"
|
||||
@@ -39,6 +41,9 @@ type JunitReportConfig struct {
|
||||
// Enable OmitSpecSemVerConstraints to prevent semantic version constraints from appearing in the spec name
|
||||
OmitSpecSemVerConstraints bool
|
||||
|
||||
// Enable OmitSpecComponentSemVerConstraints to prevent component semantic version constraints from appearing in the spec name
|
||||
OmitSpecComponentSemVerConstraints bool
|
||||
|
||||
// Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name
|
||||
OmitLeafNodeType bool
|
||||
|
||||
@@ -173,6 +178,7 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
|
||||
{"SpecialSuiteFailureReason", strings.Join(report.SpecialSuiteFailureReasons, ",")},
|
||||
{"SuiteLabels", fmt.Sprintf("[%s]", strings.Join(report.SuiteLabels, ","))},
|
||||
{"SuiteSemVerConstraints", fmt.Sprintf("[%s]", strings.Join(report.SuiteSemVerConstraints, ","))},
|
||||
{"SuiteComponentSemVerConstraints", fmt.Sprintf("[%s]", formatComponentSemVerConstraintsToString(report.SuiteComponentSemVerConstraints))},
|
||||
{"RandomSeed", fmt.Sprintf("%d", report.SuiteConfig.RandomSeed)},
|
||||
{"RandomizeAllSpecs", fmt.Sprintf("%t", report.SuiteConfig.RandomizeAllSpecs)},
|
||||
{"LabelFilter", report.SuiteConfig.LabelFilter},
|
||||
@@ -216,6 +222,10 @@ func GenerateJUnitReportWithConfig(report types.Report, dst string, config Junit
|
||||
if len(semVerConstraints) > 0 && !config.OmitSpecSemVerConstraints {
|
||||
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
|
||||
}
|
||||
componentSemVerConstraints := spec.ComponentSemVerConstraints()
|
||||
if len(componentSemVerConstraints) > 0 && !config.OmitSpecComponentSemVerConstraints {
|
||||
name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
|
||||
}
|
||||
name = strings.TrimSpace(name)
|
||||
|
||||
test := JUnitTestCase{
|
||||
@@ -387,6 +397,16 @@ func systemOutForUnstructuredReporters(spec types.SpecReport) string {
|
||||
return spec.CapturedStdOutErr
|
||||
}
|
||||
|
||||
func formatComponentSemVerConstraintsToString(componentSemVerConstraints map[string][]string) string {
|
||||
var tmpStr string
|
||||
for _, key := range slices.Sorted(maps.Keys(componentSemVerConstraints)) {
|
||||
tmpStr = tmpStr + fmt.Sprintf("%s: %s, ", key, componentSemVerConstraints[key])
|
||||
}
|
||||
|
||||
tmpStr = strings.TrimSuffix(tmpStr, ", ")
|
||||
return tmpStr
|
||||
}
|
||||
|
||||
// Deprecated JUnitReporter (so folks can still compile their suites)
|
||||
type JUnitReporter struct{}
|
||||
|
||||
|
||||
+8
@@ -39,12 +39,16 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
|
||||
name := report.SuiteDescription
|
||||
labels := report.SuiteLabels
|
||||
semVerConstraints := report.SuiteSemVerConstraints
|
||||
componentSemVerConstraints := report.SuiteComponentSemVerConstraints
|
||||
if len(labels) > 0 {
|
||||
name = name + " [" + strings.Join(labels, ", ") + "]"
|
||||
}
|
||||
if len(semVerConstraints) > 0 {
|
||||
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
|
||||
}
|
||||
if len(componentSemVerConstraints) > 0 {
|
||||
name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
|
||||
}
|
||||
fmt.Fprintf(f, "##teamcity[testSuiteStarted name='%s']\n", tcEscape(name))
|
||||
for _, spec := range report.SpecReports {
|
||||
name := fmt.Sprintf("[%s]", spec.LeafNodeType)
|
||||
@@ -59,6 +63,10 @@ func GenerateTeamcityReport(report types.Report, dst string) error {
|
||||
if len(semVerConstraints) > 0 {
|
||||
name = name + " [" + strings.Join(semVerConstraints, ", ") + "]"
|
||||
}
|
||||
componentSemVerConstraints := spec.ComponentSemVerConstraints()
|
||||
if len(componentSemVerConstraints) > 0 {
|
||||
name = name + " [" + formatComponentSemVerConstraintsToString(componentSemVerConstraints) + "]"
|
||||
}
|
||||
|
||||
name = tcEscape(name)
|
||||
fmt.Fprintf(f, "##teamcity[testStarted name='%s']\n", name)
|
||||
|
||||
+9
@@ -450,6 +450,15 @@ func (g ginkgoErrors) InvalidEmptySemVerConstraint(cl CodeLocation) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (g ginkgoErrors) InvalidEmptyComponentForSemVerConstraint(cl CodeLocation) error {
|
||||
return GinkgoError{
|
||||
Heading: "Invalid Empty Component for ComponentSemVerConstraint",
|
||||
Message: "ComponentSemVerConstraint requires a non-empty component name",
|
||||
CodeLocation: cl,
|
||||
DocLink: "spec-semantic-version-filtering",
|
||||
}
|
||||
}
|
||||
|
||||
/* Table errors */
|
||||
func (g ginkgoErrors) MultipleEntryBodyFunctionsForTable(cl CodeLocation) error {
|
||||
return GinkgoError{
|
||||
|
||||
+77
-16
@@ -2,11 +2,12 @@ package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
)
|
||||
|
||||
type SemVerFilter func([]string) bool
|
||||
type SemVerFilter func(component string, constraints []string) bool
|
||||
|
||||
func MustParseSemVerFilter(input string) SemVerFilter {
|
||||
filter, err := ParseSemVerFilter(input)
|
||||
@@ -16,30 +17,90 @@ func MustParseSemVerFilter(input string) SemVerFilter {
|
||||
return filter
|
||||
}
|
||||
|
||||
func ParseSemVerFilter(filterVersion string) (SemVerFilter, error) {
|
||||
if filterVersion == "" {
|
||||
return func(_ []string) bool { return true }, nil
|
||||
// ParseSemVerFilter parses non-component and component-specific semantic version filter string.
|
||||
// The filter string can contain multiple non-component and component-specific versions separated by commas.
|
||||
// Each component-specific version is in the format "component=version".
|
||||
// If a version is specified without a component, it applies to non-component-specific constraints.
|
||||
func ParseSemVerFilter(componentFilterVersions string) (SemVerFilter, error) {
|
||||
if componentFilterVersions == "" {
|
||||
return func(_ string, _ []string) bool { return true }, nil
|
||||
}
|
||||
|
||||
targetVersion, err := semver.NewVersion(filterVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid filter version: %w", err)
|
||||
result := map[string]*semver.Version{}
|
||||
parts := strings.Split(componentFilterVersions, ",")
|
||||
for _, part := range parts {
|
||||
part = strings.TrimSpace(part)
|
||||
if len(part) == 0 {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(part, "=") {
|
||||
// validate component-specific version string
|
||||
invalidPart, invalidErr := false, fmt.Errorf("invalid component filter version: %s", part)
|
||||
subParts := strings.Split(part, "=")
|
||||
if len(subParts) != 2 {
|
||||
invalidPart = true
|
||||
}
|
||||
component := strings.TrimSpace(subParts[0])
|
||||
versionStr := strings.TrimSpace(subParts[1])
|
||||
if len(component) == 0 || len(versionStr) == 0 {
|
||||
invalidPart = true
|
||||
}
|
||||
if invalidPart {
|
||||
return nil, invalidErr
|
||||
}
|
||||
|
||||
// validate semver
|
||||
v, err := semver.NewVersion(versionStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid component filter version: %s, error: %w", part, err)
|
||||
}
|
||||
result[component] = v
|
||||
} else {
|
||||
v, err := semver.NewVersion(part)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid filter version: %s, error: %w", part, err)
|
||||
}
|
||||
result[""] = v
|
||||
}
|
||||
}
|
||||
|
||||
return func(constraints []string) bool {
|
||||
return func(component string, constraints []string) bool {
|
||||
// unconstrained specs always run
|
||||
if len(constraints) == 0 {
|
||||
if len(component) == 0 && len(constraints) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, constraintStr := range constraints {
|
||||
constraint, err := semver.NewConstraint(constraintStr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// check non-component specific version constraints
|
||||
if len(component) == 0 && len(constraints) != 0 {
|
||||
v := result[""]
|
||||
if v != nil {
|
||||
for _, constraintStr := range constraints {
|
||||
constraint, err := semver.NewConstraint(constraintStr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if !constraint.Check(targetVersion) {
|
||||
return false
|
||||
if !constraint.Check(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check component-specific version constraints
|
||||
if len(component) != 0 && len(constraints) != 0 {
|
||||
v := result[component]
|
||||
if v != nil {
|
||||
for _, constraintStr := range constraints {
|
||||
constraint, err := semver.NewConstraint(constraintStr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if !constraint.Check(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+108
-51
@@ -38,6 +38,10 @@ type ConstructionNodeReport struct {
|
||||
// all Describe/Context/When containers in this spec's hierarchy
|
||||
ContainerHierarchySemVerConstraints [][]string
|
||||
|
||||
// ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of
|
||||
// all Describe/Context/When containers in this spec's hierarchy
|
||||
ContainerHierarchyComponentSemVerConstraints []map[string][]string
|
||||
|
||||
// IsSerial captures whether the any container has the Serial decorator
|
||||
IsSerial bool
|
||||
|
||||
@@ -85,6 +89,9 @@ type Report struct {
|
||||
//SuiteSemVerConstraints captures any semVerConstraints attached to the suite by the DSL's RunSpecs() function
|
||||
SuiteSemVerConstraints []string
|
||||
|
||||
//SuiteComponentSemVerConstraints captures any component-specific semVerConstraints attached to the suite by the DSL's RunSpecs() function
|
||||
SuiteComponentSemVerConstraints map[string][]string
|
||||
|
||||
//SuiteSucceeded captures the success or failure status of the test run
|
||||
//If true, the test run is considered successful.
|
||||
//If false, the test run is considered unsuccessful
|
||||
@@ -188,14 +195,19 @@ type SpecReport struct {
|
||||
// all Describe/Context/When containers in this spec's hierarchy
|
||||
ContainerHierarchySemVerConstraints [][]string
|
||||
|
||||
// ContainerHierarchyComponentSemVerConstraints is a slice containing the component-specific semVerConstraints of
|
||||
// all Describe/Context/When containers in this spec's hierarchy
|
||||
ContainerHierarchyComponentSemVerConstraints []map[string][]string
|
||||
|
||||
// LeafNodeType, LeafNodeLocation, LeafNodeLabels, LeafNodeSemVerConstraints and LeafNodeText capture the NodeType, CodeLocation, and text
|
||||
// of the Ginkgo node being tested (typically an NodeTypeIt node, though this can also be
|
||||
// one of the NodeTypesForSuiteLevelNodes node types)
|
||||
LeafNodeType NodeType
|
||||
LeafNodeLocation CodeLocation
|
||||
LeafNodeLabels []string
|
||||
LeafNodeSemVerConstraints []string
|
||||
LeafNodeText string
|
||||
LeafNodeType NodeType
|
||||
LeafNodeLocation CodeLocation
|
||||
LeafNodeLabels []string
|
||||
LeafNodeSemVerConstraints []string
|
||||
LeafNodeComponentSemVerConstraints map[string][]string
|
||||
LeafNodeText string
|
||||
|
||||
// Captures the Spec Priority
|
||||
SpecPriority int
|
||||
@@ -261,52 +273,54 @@ type SpecReport struct {
|
||||
func (report SpecReport) MarshalJSON() ([]byte, error) {
|
||||
//All this to avoid emitting an empty Failure struct in the JSON
|
||||
out := struct {
|
||||
ContainerHierarchyTexts []string
|
||||
ContainerHierarchyLocations []CodeLocation
|
||||
ContainerHierarchyLabels [][]string
|
||||
ContainerHierarchySemVerConstraints [][]string
|
||||
LeafNodeType NodeType
|
||||
LeafNodeLocation CodeLocation
|
||||
LeafNodeLabels []string
|
||||
LeafNodeSemVerConstraints []string
|
||||
LeafNodeText string
|
||||
State SpecState
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
RunTime time.Duration
|
||||
ParallelProcess int
|
||||
Failure *Failure `json:",omitempty"`
|
||||
NumAttempts int
|
||||
MaxFlakeAttempts int
|
||||
MaxMustPassRepeatedly int
|
||||
CapturedGinkgoWriterOutput string `json:",omitempty"`
|
||||
CapturedStdOutErr string `json:",omitempty"`
|
||||
ReportEntries ReportEntries `json:",omitempty"`
|
||||
ProgressReports []ProgressReport `json:",omitempty"`
|
||||
AdditionalFailures []AdditionalFailure `json:",omitempty"`
|
||||
SpecEvents SpecEvents `json:",omitempty"`
|
||||
ContainerHierarchyTexts []string
|
||||
ContainerHierarchyLocations []CodeLocation
|
||||
ContainerHierarchyLabels [][]string
|
||||
ContainerHierarchySemVerConstraints [][]string
|
||||
ContainerHierarchyComponentSemVerConstraints []map[string][]string
|
||||
LeafNodeType NodeType
|
||||
LeafNodeLocation CodeLocation
|
||||
LeafNodeLabels []string
|
||||
LeafNodeSemVerConstraints []string
|
||||
LeafNodeText string
|
||||
State SpecState
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
RunTime time.Duration
|
||||
ParallelProcess int
|
||||
Failure *Failure `json:",omitempty"`
|
||||
NumAttempts int
|
||||
MaxFlakeAttempts int
|
||||
MaxMustPassRepeatedly int
|
||||
CapturedGinkgoWriterOutput string `json:",omitempty"`
|
||||
CapturedStdOutErr string `json:",omitempty"`
|
||||
ReportEntries ReportEntries `json:",omitempty"`
|
||||
ProgressReports []ProgressReport `json:",omitempty"`
|
||||
AdditionalFailures []AdditionalFailure `json:",omitempty"`
|
||||
SpecEvents SpecEvents `json:",omitempty"`
|
||||
}{
|
||||
ContainerHierarchyTexts: report.ContainerHierarchyTexts,
|
||||
ContainerHierarchyLocations: report.ContainerHierarchyLocations,
|
||||
ContainerHierarchyLabels: report.ContainerHierarchyLabels,
|
||||
ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints,
|
||||
LeafNodeType: report.LeafNodeType,
|
||||
LeafNodeLocation: report.LeafNodeLocation,
|
||||
LeafNodeLabels: report.LeafNodeLabels,
|
||||
LeafNodeSemVerConstraints: report.LeafNodeSemVerConstraints,
|
||||
LeafNodeText: report.LeafNodeText,
|
||||
State: report.State,
|
||||
StartTime: report.StartTime,
|
||||
EndTime: report.EndTime,
|
||||
RunTime: report.RunTime,
|
||||
ParallelProcess: report.ParallelProcess,
|
||||
Failure: nil,
|
||||
ReportEntries: nil,
|
||||
NumAttempts: report.NumAttempts,
|
||||
MaxFlakeAttempts: report.MaxFlakeAttempts,
|
||||
MaxMustPassRepeatedly: report.MaxMustPassRepeatedly,
|
||||
CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput,
|
||||
CapturedStdOutErr: report.CapturedStdOutErr,
|
||||
ContainerHierarchyTexts: report.ContainerHierarchyTexts,
|
||||
ContainerHierarchyLocations: report.ContainerHierarchyLocations,
|
||||
ContainerHierarchyLabels: report.ContainerHierarchyLabels,
|
||||
ContainerHierarchySemVerConstraints: report.ContainerHierarchySemVerConstraints,
|
||||
ContainerHierarchyComponentSemVerConstraints: report.ContainerHierarchyComponentSemVerConstraints,
|
||||
LeafNodeType: report.LeafNodeType,
|
||||
LeafNodeLocation: report.LeafNodeLocation,
|
||||
LeafNodeLabels: report.LeafNodeLabels,
|
||||
LeafNodeSemVerConstraints: report.LeafNodeSemVerConstraints,
|
||||
LeafNodeText: report.LeafNodeText,
|
||||
State: report.State,
|
||||
StartTime: report.StartTime,
|
||||
EndTime: report.EndTime,
|
||||
RunTime: report.RunTime,
|
||||
ParallelProcess: report.ParallelProcess,
|
||||
Failure: nil,
|
||||
ReportEntries: nil,
|
||||
NumAttempts: report.NumAttempts,
|
||||
MaxFlakeAttempts: report.MaxFlakeAttempts,
|
||||
MaxMustPassRepeatedly: report.MaxMustPassRepeatedly,
|
||||
CapturedGinkgoWriterOutput: report.CapturedGinkgoWriterOutput,
|
||||
CapturedStdOutErr: report.CapturedStdOutErr,
|
||||
}
|
||||
|
||||
if !report.Failure.IsZero() {
|
||||
@@ -404,6 +418,34 @@ func (report SpecReport) SemVerConstraints() []string {
|
||||
return out
|
||||
}
|
||||
|
||||
// ComponentSemVerConstraints returns a deduped map of all the spec's component-specific SemVerConstraints.
|
||||
func (report SpecReport) ComponentSemVerConstraints() map[string][]string {
|
||||
out := map[string][]string{}
|
||||
seen := map[string]bool{}
|
||||
for _, compSemVerConstraints := range report.ContainerHierarchyComponentSemVerConstraints {
|
||||
for component := range compSemVerConstraints {
|
||||
if !seen[component] {
|
||||
seen[component] = true
|
||||
out[component] = compSemVerConstraints[component]
|
||||
} else {
|
||||
out[component] = append(out[component], compSemVerConstraints[component]...)
|
||||
out[component] = slices.Compact(out[component])
|
||||
}
|
||||
}
|
||||
}
|
||||
for component := range report.LeafNodeComponentSemVerConstraints {
|
||||
if !seen[component] {
|
||||
seen[component] = true
|
||||
out[component] = report.LeafNodeComponentSemVerConstraints[component]
|
||||
} else {
|
||||
out[component] = append(out[component], report.LeafNodeComponentSemVerConstraints[component]...)
|
||||
out[component] = slices.Compact(out[component])
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query
|
||||
func (report SpecReport) MatchesLabelFilter(query string) (bool, error) {
|
||||
filter, err := ParseLabelFilter(query)
|
||||
@@ -419,7 +461,22 @@ func (report SpecReport) MatchesSemVerFilter(version string) (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return filter(report.SemVerConstraints()), nil
|
||||
|
||||
semVerConstraints := report.SemVerConstraints()
|
||||
if len(semVerConstraints) != 0 && filter("", report.SemVerConstraints()) == false {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
componentSemVerConstraints := report.ComponentSemVerConstraints()
|
||||
if len(componentSemVerConstraints) != 0 {
|
||||
for component, constraints := range componentSemVerConstraints {
|
||||
if filter(component, constraints) == false {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// FileName() returns the name of the file containing the spec
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package types
|
||||
|
||||
const VERSION = "2.27.5"
|
||||
const VERSION = "2.28.0"
|
||||
|
||||
+4
@@ -1,3 +1,7 @@
|
||||
## 1.39.1
|
||||
|
||||
Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months.
|
||||
|
||||
## 1.39.0
|
||||
|
||||
### Features
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import (
|
||||
"github.com/onsi/gomega/types"
|
||||
)
|
||||
|
||||
const GOMEGA_VERSION = "1.39.0"
|
||||
const GOMEGA_VERSION = "1.39.1"
|
||||
|
||||
const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
|
||||
If you're using Ginkgo then you probably forgot to put your assertion in an It().
|
||||
|
||||
Reference in New Issue
Block a user