Merge pull request #28726 from containers/renovate/github.com-onsi-gomega-1.x

fix(deps): update module github.com/onsi/gomega to v1.41.0
This commit is contained in:
Paul Holzinger
2026-05-19 22:36:40 +02:00
committed by GitHub
10 changed files with 116 additions and 21 deletions

2
go.mod
View File

@@ -47,7 +47,7 @@ require (
github.com/moby/term v0.5.2
github.com/nxadm/tail v1.4.11
github.com/onsi/ginkgo/v2 v2.29.0
github.com/onsi/gomega v1.40.0
github.com/onsi/gomega v1.41.0
github.com/opencontainers/cgroups v0.0.6
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.1

4
go.sum
View File

@@ -283,8 +283,8 @@ github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/onsi/ginkgo/v2 v2.29.0 h1:rfh+ZFjgJhYWRoIqVf3Uwx/W20yLrcrE2h2GmYVRaag=
github.com/onsi/ginkgo/v2 v2.29.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA=
github.com/onsi/gomega v1.41.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
github.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI=
github.com/opencontainers/cgroups v0.0.6/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=

View File

@@ -1,3 +1,13 @@
## 1.41.0
### Features
Add `BeASlice` and `BeAnArray` matchers
### Fixes
Object formatting now detects pointer cycles to avoid runaway formatting output.
## 1.40.0
We're adopting a new release strategy to minimize dependency bloat in projects that consume Gomega. It is a limitation of the go mod toolchain that _test_ subdependencies of your project's direct dependencies get pulled in as *indirect* dependencies. In the case of Gomega, this ends up pulling in all of Ginkgo into your `go.mod` even if you are only using Gomega (Gomega uses Ginkgo for its own tests).

View File

@@ -262,7 +262,7 @@ func Object(object any, indentation uint) string {
if err, ok := object.(error); ok && !isNilValue(value) { // isNilValue check needed here to avoid nil deref due to boxed nil
commonRepresentation += "\n" + IndentString(err.Error(), indentation) + "\n" + indent
}
return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation, true))
return fmt.Sprintf("%s<%s>: %s%s", indent, formatType(value), commonRepresentation, formatValue(value, indentation, true, map[uintptr]struct{}{}))
}
/*
@@ -306,7 +306,7 @@ func formatType(v reflect.Value) string {
}
}
func formatValue(value reflect.Value, indentation uint, isTopLevel bool) string {
func formatValue(value reflect.Value, indentation uint, isTopLevel bool, visited map[uintptr]struct{}) string {
if indentation > MaxDepth {
return "..."
}
@@ -367,23 +367,28 @@ func formatValue(value reflect.Value, indentation uint, isTopLevel bool) string
case reflect.Func:
return fmt.Sprintf("0x%x", value.Pointer())
case reflect.Ptr:
return formatValue(value.Elem(), indentation, isTopLevel)
ptr := value.Pointer()
if _, ok := visited[ptr]; ok {
return fmt.Sprintf("0x%x (cyclic reference)", ptr)
}
visited[ptr] = struct{}{}
return formatValue(value.Elem(), indentation, isTopLevel, visited)
case reflect.Slice:
return truncateLongStrings(formatSlice(value, indentation))
return truncateLongStrings(formatSlice(value, indentation, visited))
case reflect.String:
return truncateLongStrings(formatString(value.String(), indentation, isTopLevel))
case reflect.Array:
return truncateLongStrings(formatSlice(value, indentation))
return truncateLongStrings(formatSlice(value, indentation, visited))
case reflect.Map:
return truncateLongStrings(formatMap(value, indentation))
return truncateLongStrings(formatMap(value, indentation, visited))
case reflect.Struct:
if value.Type() == timeType && value.CanInterface() {
t, _ := value.Interface().(time.Time)
return t.Format(time.RFC3339Nano)
}
return truncateLongStrings(formatStruct(value, indentation))
return truncateLongStrings(formatStruct(value, indentation, visited))
case reflect.Interface:
return formatInterface(value, indentation)
return formatInterface(value, indentation, visited)
default:
if value.CanInterface() {
return truncateLongStrings(fmt.Sprintf("%#v", value.Interface()))
@@ -414,7 +419,7 @@ func formatString(object any, indentation uint, isTopLevel bool) string {
}
}
func formatSlice(v reflect.Value, indentation uint) string {
func formatSlice(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string {
if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && isPrintableString(string(v.Bytes())) {
return formatString(v.Bytes(), indentation, false)
}
@@ -423,7 +428,7 @@ func formatSlice(v reflect.Value, indentation uint) string {
result := make([]string, l)
longest := 0
for i := range l {
result[i] = formatValue(v.Index(i), indentation+1, false)
result[i] = formatValue(v.Index(i), indentation+1, false, visited)
if len(result[i]) > longest {
longest = len(result[i])
}
@@ -436,14 +441,14 @@ func formatSlice(v reflect.Value, indentation uint) string {
return fmt.Sprintf("[%s]", strings.Join(result, ", "))
}
func formatMap(v reflect.Value, indentation uint) string {
func formatMap(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string {
l := v.Len()
result := make([]string, l)
longest := 0
for i, key := range v.MapKeys() {
value := v.MapIndex(key)
result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1, false), formatValue(value, indentation+1, false))
result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1, false, visited), formatValue(value, indentation+1, false, visited))
if len(result[i]) > longest {
longest = len(result[i])
}
@@ -456,7 +461,7 @@ func formatMap(v reflect.Value, indentation uint) string {
return fmt.Sprintf("{%s}", strings.Join(result, ", "))
}
func formatStruct(v reflect.Value, indentation uint) string {
func formatStruct(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string {
t := v.Type()
l := v.NumField()
@@ -465,7 +470,7 @@ func formatStruct(v reflect.Value, indentation uint) string {
for i := range l {
structField := t.Field(i)
fieldEntry := v.Field(i)
representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1, false))
representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1, false, visited))
result = append(result, representation)
if len(representation) > longest {
longest = len(representation)
@@ -478,8 +483,8 @@ func formatStruct(v reflect.Value, indentation uint) string {
return fmt.Sprintf("{%s}", strings.Join(result, ", "))
}
func formatInterface(v reflect.Value, indentation uint) string {
return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation, false))
func formatInterface(v reflect.Value, indentation uint, visited map[uintptr]struct{}) string {
return fmt.Sprintf("<%s>%s", formatType(v.Elem()), formatValue(v.Elem(), indentation, false, visited))
}
func isNilValue(a reflect.Value) bool {

View File

@@ -22,7 +22,7 @@ import (
"github.com/onsi/gomega/types"
)
const GOMEGA_VERSION = "1.40.0"
const GOMEGA_VERSION = "1.41.0"
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().

View File

@@ -621,6 +621,18 @@ func BeADirectory() types.GomegaMatcher {
return &matchers.BeADirectoryMatcher{}
}
// BeASlice succeeds if actual is a value of slice type.
// This is useful when actual has type any (interface{}) and you want to assert it is a slice.
func BeASlice() types.GomegaMatcher {
return &matchers.BeASliceMatcher{}
}
// BeAnArray succeeds if actual is a value of array type.
// This is useful when actual has type any (interface{}) and you want to assert it is an array.
func BeAnArray() types.GomegaMatcher {
return &matchers.BeAnArrayMatcher{}
}
// HaveHTTPStatus succeeds if the Status or StatusCode field of an HTTP response matches.
// Actual must be either a *http.Response or *httptest.ResponseRecorder.
// Expected must be either an int or a string.

View File

@@ -0,0 +1,28 @@
// untested sections: 1
package matchers
import (
"fmt"
"reflect"
"github.com/onsi/gomega/format"
)
type BeASliceMatcher struct {
}
func (matcher *BeASliceMatcher) Match(actual any) (success bool, err error) {
if actual == nil {
return false, fmt.Errorf("BeASlice matcher expects a value, got nil")
}
return reflect.TypeOf(actual).Kind() == reflect.Slice, nil
}
func (matcher *BeASliceMatcher) FailureMessage(actual any) (message string) {
return format.Message(actual, "to be a slice")
}
func (matcher *BeASliceMatcher) NegatedFailureMessage(actual any) (message string) {
return format.Message(actual, "not to be a slice")
}

View File

@@ -0,0 +1,28 @@
// untested sections: 1
package matchers
import (
"fmt"
"reflect"
"github.com/onsi/gomega/format"
)
type BeAnArrayMatcher struct {
}
func (matcher *BeAnArrayMatcher) Match(actual any) (success bool, err error) {
if actual == nil {
return false, fmt.Errorf("BeAnArray matcher expects a value, got nil")
}
return reflect.TypeOf(actual).Kind() == reflect.Array, nil
}
func (matcher *BeAnArrayMatcher) FailureMessage(actual any) (message string) {
return format.Message(actual, "to be an array")
}
func (matcher *BeAnArrayMatcher) NegatedFailureMessage(actual any) (message string) {
return format.Message(actual, "not to be an array")
}

View File

@@ -66,6 +66,12 @@ func MatchMayChangeInTheFuture(matcher GomegaMatcher, value any) bool {
// AsyncAssertions are returned by Eventually and Consistently and enable matchers to be polled repeatedly to ensure
// they are eventually satisfied
//
// The optional optionalDescription argument allows you to annotate the assertion with additional information.
// It is passed as the second argument and can be a format string followed by arguments, or a func() string.
// The description is included in failure messages to provide context.
//
// For details on annotating assertions, see: https://onsi.github.io/gomega/#annotating-assertions
type AsyncAssertion interface {
Should(matcher GomegaMatcher, optionalDescription ...any) bool
ShouldNot(matcher GomegaMatcher, optionalDescription ...any) bool
@@ -86,6 +92,12 @@ type AsyncAssertion interface {
}
// Assertions are returned by Ω and Expect and enable assertions against Gomega matchers
//
// The optional optionalDescription argument allows you to annotate the assertion with additional information.
// It is passed as the second argument and can be a format string followed by arguments, or a func() string.
// The description is included in failure messages to provide context.
//
// For details on annotating assertions, see: https://onsi.github.io/gomega/#annotating-assertions
type Assertion interface {
Should(matcher GomegaMatcher, optionalDescription ...any) bool
ShouldNot(matcher GomegaMatcher, optionalDescription ...any) bool

2
vendor/modules.txt vendored
View File

@@ -467,7 +467,7 @@ github.com/onsi/ginkgo/v2/internal/reporters
github.com/onsi/ginkgo/v2/internal/testingtproxy
github.com/onsi/ginkgo/v2/reporters
github.com/onsi/ginkgo/v2/types
# github.com/onsi/gomega v1.40.0
# github.com/onsi/gomega v1.41.0
## explicit; go 1.24.0
github.com/onsi/gomega
github.com/onsi/gomega/format