Compare commits

..

1 commit

Author SHA1 Message Date
12f0088e99 chore(deps): update module github.com/stretchr/testify to v1.10.0
Some checks failed
Dev Version / Release (push) Has been cancelled
2024-11-29 23:39:40 +00:00
13 changed files with 184 additions and 377 deletions

2
go.mod
View file

@ -6,7 +6,7 @@ require (
github.com/aws/aws-sdk-go v1.55.5 github.com/aws/aws-sdk-go v1.55.5
github.com/pkg/sftp v1.13.6 github.com/pkg/sftp v1.13.6
github.com/rs/zerolog v1.33.0 github.com/rs/zerolog v1.33.0
github.com/stretchr/testify v1.11.1 github.com/stretchr/testify v1.10.0
github.com/urfave/cli/v2 v2.27.4 github.com/urfave/cli/v2 v2.27.4
golang.org/x/crypto v0.27.0 golang.org/x/crypto v0.27.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1

4
go.sum
View file

@ -42,8 +42,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=

View file

@ -390,8 +390,7 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
} }
failMessage := fmt.Sprintf("\"%v\" is not greater than \"%v\"", e1, e2) return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...)
return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, failMessage, msgAndArgs...)
} }
// GreaterOrEqual asserts that the first element is greater than or equal to the second // GreaterOrEqual asserts that the first element is greater than or equal to the second
@ -404,8 +403,7 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
} }
failMessage := fmt.Sprintf("\"%v\" is not greater than or equal to \"%v\"", e1, e2) return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...)
return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, failMessage, msgAndArgs...)
} }
// Less asserts that the first element is less than the second // Less asserts that the first element is less than the second
@ -417,8 +415,7 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{})
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
} }
failMessage := fmt.Sprintf("\"%v\" is not less than \"%v\"", e1, e2) return compareTwoValues(t, e1, e2, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...)
return compareTwoValues(t, e1, e2, []compareResult{compareLess}, failMessage, msgAndArgs...)
} }
// LessOrEqual asserts that the first element is less than or equal to the second // LessOrEqual asserts that the first element is less than or equal to the second
@ -431,8 +428,7 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
} }
failMessage := fmt.Sprintf("\"%v\" is not less than or equal to \"%v\"", e1, e2) return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...)
return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, failMessage, msgAndArgs...)
} }
// Positive asserts that the specified element is positive // Positive asserts that the specified element is positive
@ -444,8 +440,7 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
h.Helper() h.Helper()
} }
zero := reflect.Zero(reflect.TypeOf(e)) zero := reflect.Zero(reflect.TypeOf(e))
failMessage := fmt.Sprintf("\"%v\" is not positive", e) return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, "\"%v\" is not positive", msgAndArgs...)
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, failMessage, msgAndArgs...)
} }
// Negative asserts that the specified element is negative // Negative asserts that the specified element is negative
@ -457,8 +452,7 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
h.Helper() h.Helper()
} }
zero := reflect.Zero(reflect.TypeOf(e)) zero := reflect.Zero(reflect.TypeOf(e))
failMessage := fmt.Sprintf("\"%v\" is not negative", e) return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, "\"%v\" is not negative", msgAndArgs...)
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, failMessage, msgAndArgs...)
} }
func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool {
@ -474,11 +468,11 @@ func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedCompare
compareResult, isComparable := compare(e1, e2, e1Kind) compareResult, isComparable := compare(e1, e2, e1Kind)
if !isComparable { if !isComparable {
return Fail(t, fmt.Sprintf(`Can not compare type "%T"`, e1), msgAndArgs...) return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...)
} }
if !containsValue(allowedComparesResults, compareResult) { if !containsValue(allowedComparesResults, compareResult) {
return Fail(t, failMessage, msgAndArgs...) return Fail(t, fmt.Sprintf(failMessage, e1, e2), msgAndArgs...)
} }
return true return true

View file

@ -50,19 +50,10 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
} }
// Emptyf asserts that the given value is "empty". // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
// // a slice or a channel with len == 0.
// [Zero values] are "empty".
//
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
//
// Slices, maps and channels with zero length are "empty".
//
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
// //
// assert.Emptyf(t, obj, "error message %s", "formatted") // assert.Emptyf(t, obj, "error message %s", "formatted")
//
// [Zero values]: https://go.dev/ref/spec#The_zero_value
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
@ -126,8 +117,10 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
// Errorf asserts that a function returned an error (i.e. not `nil`). // Errorf asserts that a function returned an error (i.e. not `nil`).
// //
// actualObj, err := SomeFunction() // actualObj, err := SomeFunction()
// assert.Errorf(t, err, "error message %s", "formatted") // if assert.Errorf(t, err, "error message %s", "formatted") {
// assert.Equal(t, expectedErrorf, err)
// }
func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
@ -445,19 +438,7 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf
return IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...) return IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...)
} }
// IsNotTypef asserts that the specified objects are not of the same type.
//
// assert.IsNotTypef(t, &NotMyStruct{}, &MyStruct{}, "error message %s", "formatted")
func IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
return IsNotType(t, theType, object, append([]interface{}{msg}, args...)...)
}
// IsTypef asserts that the specified objects are of the same type. // IsTypef asserts that the specified objects are of the same type.
//
// assert.IsTypef(t, &MyStruct{}, &MyStruct{}, "error message %s", "formatted")
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
@ -604,7 +585,8 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str
return NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) return NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
} }
// NotEmptyf asserts that the specified object is NOT [Empty]. // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
// a slice or a channel with len == 0.
// //
// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { // if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
// assert.Equal(t, "two", obj[1]) // assert.Equal(t, "two", obj[1])
@ -711,15 +693,12 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...) return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)
} }
// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all // NotSubsetf asserts that the specified list(array, slice...) or map does NOT
// elements given in the subset (array, slice, or map). // contain all elements given in the specified subset list(array, slice...) or
// Map elements are key-value pairs unless compared with an array or slice where // map.
// only the map key is evaluated.
// //
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") // assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") // assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
// assert.NotSubsetf(t, [1, 3, 4], {1: "one", 2: "two"}, "error message %s", "formatted")
// assert.NotSubsetf(t, {"x": 1, "y": 2}, ["z"], "error message %s", "formatted")
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
@ -803,15 +782,11 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
return Same(t, expected, actual, append([]interface{}{msg}, args...)...) return Same(t, expected, actual, append([]interface{}{msg}, args...)...)
} }
// Subsetf asserts that the list (array, slice, or map) contains all elements // Subsetf asserts that the specified list(array, slice...) or map contains all
// given in the subset (array, slice, or map). // elements given in the specified subset list(array, slice...) or map.
// Map elements are key-value pairs unless compared with an array or slice where
// only the map key is evaluated.
// //
// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") // assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") // assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
// assert.Subsetf(t, [1, 2, 3], {1: "one", 2: "two"}, "error message %s", "formatted")
// assert.Subsetf(t, {"x": 1, "y": 2}, ["x"], "error message %s", "formatted")
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()

View file

@ -92,19 +92,10 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
return ElementsMatchf(a.t, listA, listB, msg, args...) return ElementsMatchf(a.t, listA, listB, msg, args...)
} }
// Empty asserts that the given value is "empty". // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
// // a slice or a channel with len == 0.
// [Zero values] are "empty".
//
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
//
// Slices, maps and channels with zero length are "empty".
//
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
// //
// a.Empty(obj) // a.Empty(obj)
//
// [Zero values]: https://go.dev/ref/spec#The_zero_value
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -112,19 +103,10 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
return Empty(a.t, object, msgAndArgs...) return Empty(a.t, object, msgAndArgs...)
} }
// Emptyf asserts that the given value is "empty". // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
// // a slice or a channel with len == 0.
// [Zero values] are "empty".
//
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
//
// Slices, maps and channels with zero length are "empty".
//
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
// //
// a.Emptyf(obj, "error message %s", "formatted") // a.Emptyf(obj, "error message %s", "formatted")
//
// [Zero values]: https://go.dev/ref/spec#The_zero_value
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -242,8 +224,10 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
// Error asserts that a function returned an error (i.e. not `nil`). // Error asserts that a function returned an error (i.e. not `nil`).
// //
// actualObj, err := SomeFunction() // actualObj, err := SomeFunction()
// a.Error(err) // if a.Error(err) {
// assert.Equal(t, expectedError, err)
// }
func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -313,8 +297,10 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter
// Errorf asserts that a function returned an error (i.e. not `nil`). // Errorf asserts that a function returned an error (i.e. not `nil`).
// //
// actualObj, err := SomeFunction() // actualObj, err := SomeFunction()
// a.Errorf(err, "error message %s", "formatted") // if a.Errorf(err, "error message %s", "formatted") {
// assert.Equal(t, expectedErrorf, err)
// }
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -882,29 +868,7 @@ func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...in
return IsNonIncreasingf(a.t, object, msg, args...) return IsNonIncreasingf(a.t, object, msg, args...)
} }
// IsNotType asserts that the specified objects are not of the same type.
//
// a.IsNotType(&NotMyStruct{}, &MyStruct{})
func (a *Assertions) IsNotType(theType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
return IsNotType(a.t, theType, object, msgAndArgs...)
}
// IsNotTypef asserts that the specified objects are not of the same type.
//
// a.IsNotTypef(&NotMyStruct{}, &MyStruct{}, "error message %s", "formatted")
func (a *Assertions) IsNotTypef(theType interface{}, object interface{}, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok {
h.Helper()
}
return IsNotTypef(a.t, theType, object, msg, args...)
}
// IsType asserts that the specified objects are of the same type. // IsType asserts that the specified objects are of the same type.
//
// a.IsType(&MyStruct{}, &MyStruct{})
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -913,8 +877,6 @@ func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAnd
} }
// IsTypef asserts that the specified objects are of the same type. // IsTypef asserts that the specified objects are of the same type.
//
// a.IsTypef(&MyStruct{}, &MyStruct{}, "error message %s", "formatted")
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -1200,7 +1162,8 @@ func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg
return NotElementsMatchf(a.t, listA, listB, msg, args...) return NotElementsMatchf(a.t, listA, listB, msg, args...)
} }
// NotEmpty asserts that the specified object is NOT [Empty]. // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
// a slice or a channel with len == 0.
// //
// if a.NotEmpty(obj) { // if a.NotEmpty(obj) {
// assert.Equal(t, "two", obj[1]) // assert.Equal(t, "two", obj[1])
@ -1212,7 +1175,8 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo
return NotEmpty(a.t, object, msgAndArgs...) return NotEmpty(a.t, object, msgAndArgs...)
} }
// NotEmptyf asserts that the specified object is NOT [Empty]. // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
// a slice or a channel with len == 0.
// //
// if a.NotEmptyf(obj, "error message %s", "formatted") { // if a.NotEmptyf(obj, "error message %s", "formatted") {
// assert.Equal(t, "two", obj[1]) // assert.Equal(t, "two", obj[1])
@ -1414,15 +1378,12 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri
return NotSamef(a.t, expected, actual, msg, args...) return NotSamef(a.t, expected, actual, msg, args...)
} }
// NotSubset asserts that the list (array, slice, or map) does NOT contain all // NotSubset asserts that the specified list(array, slice...) or map does NOT
// elements given in the subset (array, slice, or map). // contain all elements given in the specified subset list(array, slice...) or
// Map elements are key-value pairs unless compared with an array or slice where // map.
// only the map key is evaluated.
// //
// a.NotSubset([1, 3, 4], [1, 2]) // a.NotSubset([1, 3, 4], [1, 2])
// a.NotSubset({"x": 1, "y": 2}, {"z": 3}) // a.NotSubset({"x": 1, "y": 2}, {"z": 3})
// a.NotSubset([1, 3, 4], {1: "one", 2: "two"})
// a.NotSubset({"x": 1, "y": 2}, ["z"])
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -1430,15 +1391,12 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
return NotSubset(a.t, list, subset, msgAndArgs...) return NotSubset(a.t, list, subset, msgAndArgs...)
} }
// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all // NotSubsetf asserts that the specified list(array, slice...) or map does NOT
// elements given in the subset (array, slice, or map). // contain all elements given in the specified subset list(array, slice...) or
// Map elements are key-value pairs unless compared with an array or slice where // map.
// only the map key is evaluated.
// //
// a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted") // a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted")
// a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") // a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
// a.NotSubsetf([1, 3, 4], {1: "one", 2: "two"}, "error message %s", "formatted")
// a.NotSubsetf({"x": 1, "y": 2}, ["z"], "error message %s", "formatted")
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -1598,15 +1556,11 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string,
return Samef(a.t, expected, actual, msg, args...) return Samef(a.t, expected, actual, msg, args...)
} }
// Subset asserts that the list (array, slice, or map) contains all elements // Subset asserts that the specified list(array, slice...) or map contains all
// given in the subset (array, slice, or map). // elements given in the specified subset list(array, slice...) or map.
// Map elements are key-value pairs unless compared with an array or slice where
// only the map key is evaluated.
// //
// a.Subset([1, 2, 3], [1, 2]) // a.Subset([1, 2, 3], [1, 2])
// a.Subset({"x": 1, "y": 2}, {"x": 1}) // a.Subset({"x": 1, "y": 2}, {"x": 1})
// a.Subset([1, 2, 3], {1: "one", 2: "two"})
// a.Subset({"x": 1, "y": 2}, ["x"])
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()
@ -1614,15 +1568,11 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
return Subset(a.t, list, subset, msgAndArgs...) return Subset(a.t, list, subset, msgAndArgs...)
} }
// Subsetf asserts that the list (array, slice, or map) contains all elements // Subsetf asserts that the specified list(array, slice...) or map contains all
// given in the subset (array, slice, or map). // elements given in the specified subset list(array, slice...) or map.
// Map elements are key-value pairs unless compared with an array or slice where
// only the map key is evaluated.
// //
// a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted") // a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted")
// a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") // a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
// a.Subsetf([1, 2, 3], {1: "one", 2: "two"}, "error message %s", "formatted")
// a.Subsetf({"x": 1, "y": 2}, ["x"], "error message %s", "formatted")
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
if h, ok := a.t.(tHelper); ok { if h, ok := a.t.(tHelper); ok {
h.Helper() h.Helper()

View file

@ -33,7 +33,7 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR
compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind) compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind)
if !isComparable { if !isComparable {
return Fail(t, fmt.Sprintf(`Can not compare type "%T" and "%T"`, value, prevValue), msgAndArgs...) return Fail(t, fmt.Sprintf("Can not compare type \"%s\" and \"%s\"", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...)
} }
if !containsValue(allowedComparesResults, compareResult) { if !containsValue(allowedComparesResults, compareResult) {

View file

@ -210,77 +210,59 @@ the problem actually occurred in calling code.*/
// of each stack frame leading from the current test to the assert call that // of each stack frame leading from the current test to the assert call that
// failed. // failed.
func CallerInfo() []string { func CallerInfo() []string {
var pc uintptr var pc uintptr
var ok bool
var file string var file string
var line int var line int
var name string var name string
const stackFrameBufferSize = 10
pcs := make([]uintptr, stackFrameBufferSize)
callers := []string{} callers := []string{}
offset := 1 for i := 0; ; i++ {
pc, file, line, ok = runtime.Caller(i)
for { if !ok {
n := runtime.Callers(offset, pcs) // The breaks below failed to terminate the loop, and we ran off the
// end of the call stack.
if n == 0 {
break break
} }
frames := runtime.CallersFrames(pcs[:n]) // This is a huge edge case, but it will panic if this is the case, see #180
if file == "<autogenerated>" {
break
}
for { f := runtime.FuncForPC(pc)
frame, more := frames.Next() if f == nil {
pc = frame.PC break
file = frame.File }
line = frame.Line name = f.Name()
// This is a huge edge case, but it will panic if this is the case, see #180 // testing.tRunner is the standard library function that calls
if file == "<autogenerated>" { // tests. Subtests are called directly by tRunner, without going through
break // the Test/Benchmark/Example function that contains the t.Run calls, so
} // with subtests we should break when we hit tRunner, without adding it
// to the list of callers.
if name == "testing.tRunner" {
break
}
f := runtime.FuncForPC(pc) parts := strings.Split(file, "/")
if f == nil { if len(parts) > 1 {
break filename := parts[len(parts)-1]
} dir := parts[len(parts)-2]
name = f.Name() if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" {
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
// testing.tRunner is the standard library function that calls
// tests. Subtests are called directly by tRunner, without going through
// the Test/Benchmark/Example function that contains the t.Run calls, so
// with subtests we should break when we hit tRunner, without adding it
// to the list of callers.
if name == "testing.tRunner" {
break
}
parts := strings.Split(file, "/")
if len(parts) > 1 {
filename := parts[len(parts)-1]
dir := parts[len(parts)-2]
if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" {
callers = append(callers, fmt.Sprintf("%s:%d", file, line))
}
}
// Drop the package
dotPos := strings.LastIndexByte(name, '.')
name = name[dotPos+1:]
if isTest(name, "Test") ||
isTest(name, "Benchmark") ||
isTest(name, "Example") {
break
}
if !more {
break
} }
} }
// Next batch // Drop the package
offset += cap(pcs) segments := strings.Split(name, ".")
name = segments[len(segments)-1]
if isTest(name, "Test") ||
isTest(name, "Benchmark") ||
isTest(name, "Example") {
break
}
} }
return callers return callers
@ -455,34 +437,17 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{},
return true return true
} }
func isType(expectedType, object interface{}) bool {
return ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType))
}
// IsType asserts that the specified objects are of the same type. // IsType asserts that the specified objects are of the same type.
// func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
// assert.IsType(t, &MyStruct{}, &MyStruct{})
func IsType(t TestingT, expectedType, object interface{}, msgAndArgs ...interface{}) bool {
if isType(expectedType, object) {
return true
}
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
} }
return Fail(t, fmt.Sprintf("Object expected to be of type %T, but was %T", expectedType, object), msgAndArgs...)
}
// IsNotType asserts that the specified objects are not of the same type. if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
// return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
// assert.IsNotType(t, &NotMyStruct{}, &MyStruct{})
func IsNotType(t TestingT, theType, object interface{}, msgAndArgs ...interface{}) bool {
if !isType(theType, object) {
return true
} }
if h, ok := t.(tHelper); ok {
h.Helper() return true
}
return Fail(t, fmt.Sprintf("Object type expected to be different than %T", theType), msgAndArgs...)
} }
// Equal asserts that two objects are equal. // Equal asserts that two objects are equal.
@ -510,6 +475,7 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{})
} }
return true return true
} }
// validateEqualArgs checks whether provided arguments can be safely used in the // validateEqualArgs checks whether provided arguments can be safely used in the
@ -544,9 +510,8 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b
if !same { if !same {
// both are pointers but not the same type & pointing to the same address // both are pointers but not the same type & pointing to the same address
return Fail(t, fmt.Sprintf("Not same: \n"+ return Fail(t, fmt.Sprintf("Not same: \n"+
"expected: %p %#[1]v\n"+ "expected: %p %#v\n"+
"actual : %p %#[2]v", "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...)
expected, actual), msgAndArgs...)
} }
return true return true
@ -565,14 +530,14 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
same, ok := samePointers(expected, actual) same, ok := samePointers(expected, actual)
if !ok { if !ok {
// fails when the arguments are not pointers //fails when the arguments are not pointers
return !(Fail(t, "Both arguments must be pointers", msgAndArgs...)) return !(Fail(t, "Both arguments must be pointers", msgAndArgs...))
} }
if same { if same {
return Fail(t, fmt.Sprintf( return Fail(t, fmt.Sprintf(
"Expected and actual point to the same object: %p %#[1]v", "Expected and actual point to the same object: %p %#v",
expected), msgAndArgs...) expected, expected), msgAndArgs...)
} }
return true return true
} }
@ -584,7 +549,7 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
func samePointers(first, second interface{}) (same bool, ok bool) { func samePointers(first, second interface{}) (same bool, ok bool) {
firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second)
if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr {
return false, false // not both are pointers return false, false //not both are pointers
} }
firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second)
@ -645,6 +610,7 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa
} }
return true return true
} }
// EqualExportedValues asserts that the types of two objects are equal and their public // EqualExportedValues asserts that the types of two objects are equal and their public
@ -699,6 +665,7 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
} }
return Equal(t, expected, actual, msgAndArgs...) return Equal(t, expected, actual, msgAndArgs...)
} }
// NotNil asserts that the specified object is not nil. // NotNil asserts that the specified object is not nil.
@ -748,45 +715,37 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
// isEmpty gets whether the specified object is considered empty or not. // isEmpty gets whether the specified object is considered empty or not.
func isEmpty(object interface{}) bool { func isEmpty(object interface{}) bool {
// get nil case out of the way // get nil case out of the way
if object == nil { if object == nil {
return true return true
} }
return isEmptyValue(reflect.ValueOf(object)) objValue := reflect.ValueOf(object)
}
// isEmptyValue gets whether the specified reflect.Value is considered empty or not.
func isEmptyValue(objValue reflect.Value) bool {
if objValue.IsZero() {
return true
}
// Special cases of non-zero values that we consider empty
switch objValue.Kind() { switch objValue.Kind() {
// collection types are empty when they have no element // collection types are empty when they have no element
// Note: array types are empty when they match their zero-initialized state.
case reflect.Chan, reflect.Map, reflect.Slice: case reflect.Chan, reflect.Map, reflect.Slice:
return objValue.Len() == 0 return objValue.Len() == 0
// non-nil pointers are empty if the value they point to is empty // pointers are empty if nil or if the value they point to is empty
case reflect.Ptr: case reflect.Ptr:
return isEmptyValue(objValue.Elem()) if objValue.IsNil() {
return true
}
deref := objValue.Elem().Interface()
return isEmpty(deref)
// for all other types, compare against the zero value
// array types are empty when they match their zero-initialized state
default:
zero := reflect.Zero(objValue.Type())
return reflect.DeepEqual(object, zero.Interface())
} }
return false
} }
// Empty asserts that the given value is "empty". // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
// // a slice or a channel with len == 0.
// [Zero values] are "empty".
//
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
//
// Slices, maps and channels with zero length are "empty".
//
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
// //
// assert.Empty(t, obj) // assert.Empty(t, obj)
//
// [Zero values]: https://go.dev/ref/spec#The_zero_value
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
pass := isEmpty(object) pass := isEmpty(object)
if !pass { if !pass {
@ -797,9 +756,11 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
} }
return pass return pass
} }
// NotEmpty asserts that the specified object is NOT [Empty]. // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
// a slice or a channel with len == 0.
// //
// if assert.NotEmpty(t, obj) { // if assert.NotEmpty(t, obj) {
// assert.Equal(t, "two", obj[1]) // assert.Equal(t, "two", obj[1])
@ -814,6 +775,7 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
} }
return pass return pass
} }
// getLen tries to get the length of an object. // getLen tries to get the length of an object.
@ -857,6 +819,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
} }
return true return true
} }
// False asserts that the specified value is false. // False asserts that the specified value is false.
@ -871,6 +834,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
} }
return true return true
} }
// NotEqual asserts that the specified values are NOT equal. // NotEqual asserts that the specified values are NOT equal.
@ -893,6 +857,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{
} }
return true return true
} }
// NotEqualValues asserts that two objects are not equal even when converted to the same type // NotEqualValues asserts that two objects are not equal even when converted to the same type
@ -915,6 +880,7 @@ func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...inte
// return (true, false) if element was not found. // return (true, false) if element was not found.
// return (true, true) if element was found. // return (true, true) if element was found.
func containsElement(list interface{}, element interface{}) (ok, found bool) { func containsElement(list interface{}, element interface{}) (ok, found bool) {
listValue := reflect.ValueOf(list) listValue := reflect.ValueOf(list)
listType := reflect.TypeOf(list) listType := reflect.TypeOf(list)
if listType == nil { if listType == nil {
@ -949,6 +915,7 @@ func containsElement(list interface{}, element interface{}) (ok, found bool) {
} }
} }
return true, false return true, false
} }
// Contains asserts that the specified string, list(array, slice...) or map contains the // Contains asserts that the specified string, list(array, slice...) or map contains the
@ -971,6 +938,7 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
} }
return true return true
} }
// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
@ -993,17 +961,14 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
} }
return true return true
} }
// Subset asserts that the list (array, slice, or map) contains all elements // Subset asserts that the specified list(array, slice...) or map contains all
// given in the subset (array, slice, or map). // elements given in the specified subset list(array, slice...) or map.
// Map elements are key-value pairs unless compared with an array or slice where
// only the map key is evaluated.
// //
// assert.Subset(t, [1, 2, 3], [1, 2]) // assert.Subset(t, [1, 2, 3], [1, 2])
// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1}) // assert.Subset(t, {"x": 1, "y": 2}, {"x": 1})
// assert.Subset(t, [1, 2, 3], {1: "one", 2: "two"})
// assert.Subset(t, {"x": 1, "y": 2}, ["x"])
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
@ -1018,7 +983,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
} }
subsetKind := reflect.TypeOf(subset).Kind() subsetKind := reflect.TypeOf(subset).Kind()
if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map { if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
} }
@ -1042,13 +1007,6 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
} }
subsetList := reflect.ValueOf(subset) subsetList := reflect.ValueOf(subset)
if subsetKind == reflect.Map {
keys := make([]interface{}, subsetList.Len())
for idx, key := range subsetList.MapKeys() {
keys[idx] = key.Interface()
}
subsetList = reflect.ValueOf(keys)
}
for i := 0; i < subsetList.Len(); i++ { for i := 0; i < subsetList.Len(); i++ {
element := subsetList.Index(i).Interface() element := subsetList.Index(i).Interface()
ok, found := containsElement(list, element) ok, found := containsElement(list, element)
@ -1063,15 +1021,12 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
return true return true
} }
// NotSubset asserts that the list (array, slice, or map) does NOT contain all // NotSubset asserts that the specified list(array, slice...) or map does NOT
// elements given in the subset (array, slice, or map). // contain all elements given in the specified subset list(array, slice...) or
// Map elements are key-value pairs unless compared with an array or slice where // map.
// only the map key is evaluated.
// //
// assert.NotSubset(t, [1, 3, 4], [1, 2]) // assert.NotSubset(t, [1, 3, 4], [1, 2])
// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) // assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
// assert.NotSubset(t, [1, 3, 4], {1: "one", 2: "two"})
// assert.NotSubset(t, {"x": 1, "y": 2}, ["z"])
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
h.Helper() h.Helper()
@ -1086,7 +1041,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
} }
subsetKind := reflect.TypeOf(subset).Kind() subsetKind := reflect.TypeOf(subset).Kind()
if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map { if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
} }
@ -1110,18 +1065,11 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
} }
subsetList := reflect.ValueOf(subset) subsetList := reflect.ValueOf(subset)
if subsetKind == reflect.Map {
keys := make([]interface{}, subsetList.Len())
for idx, key := range subsetList.MapKeys() {
keys[idx] = key.Interface()
}
subsetList = reflect.ValueOf(keys)
}
for i := 0; i < subsetList.Len(); i++ { for i := 0; i < subsetList.Len(); i++ {
element := subsetList.Index(i).Interface() element := subsetList.Index(i).Interface()
ok, found := containsElement(list, element) ok, found := containsElement(list, element)
if !ok { if !ok {
return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", list), msgAndArgs...) return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...)
} }
if !found { if !found {
return true return true
@ -1643,8 +1591,10 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
// Error asserts that a function returned an error (i.e. not `nil`). // Error asserts that a function returned an error (i.e. not `nil`).
// //
// actualObj, err := SomeFunction() // actualObj, err := SomeFunction()
// assert.Error(t, err) // if assert.Error(t, err) {
// assert.Equal(t, expectedError, err)
// }
func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
if err == nil { if err == nil {
if h, ok := t.(tHelper); ok { if h, ok := t.(tHelper); ok {
@ -1717,6 +1667,7 @@ func matchRegexp(rx interface{}, str interface{}) bool {
default: default:
return r.MatchString(fmt.Sprint(v)) return r.MatchString(fmt.Sprint(v))
} }
} }
// Regexp asserts that a specified regexp matches a string. // Regexp asserts that a specified regexp matches a string.
@ -1752,6 +1703,7 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
} }
return !match return !match
} }
// Zero asserts that i is the zero value for its type. // Zero asserts that i is the zero value for its type.
@ -1862,11 +1814,6 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{
return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...)
} }
// Shortcut if same bytes
if actual == expected {
return true
}
if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {
return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
} }
@ -1885,11 +1832,6 @@ func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{
return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...) return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...)
} }
// Shortcut if same bytes
if actual == expected {
return true
}
if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil { if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil {
return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...) return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...)
} }
@ -1991,7 +1933,6 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t
} }
ch := make(chan bool, 1) ch := make(chan bool, 1)
checkCond := func() { ch <- condition() }
timer := time.NewTimer(waitFor) timer := time.NewTimer(waitFor)
defer timer.Stop() defer timer.Stop()
@ -1999,23 +1940,18 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t
ticker := time.NewTicker(tick) ticker := time.NewTicker(tick)
defer ticker.Stop() defer ticker.Stop()
var tickC <-chan time.Time for tick := ticker.C; ; {
// Check the condition once first on the initial call.
go checkCond()
for {
select { select {
case <-timer.C: case <-timer.C:
return Fail(t, "Condition never satisfied", msgAndArgs...) return Fail(t, "Condition never satisfied", msgAndArgs...)
case <-tickC: case <-tick:
tickC = nil tick = nil
go checkCond() go func() { ch <- condition() }()
case v := <-ch: case v := <-ch:
if v { if v {
return true return true
} }
tickC = ticker.C tick = ticker.C
} }
} }
} }
@ -2028,9 +1964,6 @@ type CollectT struct {
errors []error errors []error
} }
// Helper is like [testing.T.Helper] but does nothing.
func (CollectT) Helper() {}
// Errorf collects the error. // Errorf collects the error.
func (c *CollectT) Errorf(format string, args ...interface{}) { func (c *CollectT) Errorf(format string, args ...interface{}) {
c.errors = append(c.errors, fmt.Errorf(format, args...)) c.errors = append(c.errors, fmt.Errorf(format, args...))
@ -2088,42 +2021,35 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
var lastFinishedTickErrs []error var lastFinishedTickErrs []error
ch := make(chan *CollectT, 1) ch := make(chan *CollectT, 1)
checkCond := func() {
collect := new(CollectT)
defer func() {
ch <- collect
}()
condition(collect)
}
timer := time.NewTimer(waitFor) timer := time.NewTimer(waitFor)
defer timer.Stop() defer timer.Stop()
ticker := time.NewTicker(tick) ticker := time.NewTicker(tick)
defer ticker.Stop() defer ticker.Stop()
var tickC <-chan time.Time for tick := ticker.C; ; {
// Check the condition once first on the initial call.
go checkCond()
for {
select { select {
case <-timer.C: case <-timer.C:
for _, err := range lastFinishedTickErrs { for _, err := range lastFinishedTickErrs {
t.Errorf("%v", err) t.Errorf("%v", err)
} }
return Fail(t, "Condition never satisfied", msgAndArgs...) return Fail(t, "Condition never satisfied", msgAndArgs...)
case <-tickC: case <-tick:
tickC = nil tick = nil
go checkCond() go func() {
collect := new(CollectT)
defer func() {
ch <- collect
}()
condition(collect)
}()
case collect := <-ch: case collect := <-ch:
if !collect.failed() { if !collect.failed() {
return true return true
} }
// Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached. // Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached.
lastFinishedTickErrs = collect.errors lastFinishedTickErrs = collect.errors
tickC = ticker.C tick = ticker.C
} }
} }
} }
@ -2138,7 +2064,6 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D
} }
ch := make(chan bool, 1) ch := make(chan bool, 1)
checkCond := func() { ch <- condition() }
timer := time.NewTimer(waitFor) timer := time.NewTimer(waitFor)
defer timer.Stop() defer timer.Stop()
@ -2146,23 +2071,18 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D
ticker := time.NewTicker(tick) ticker := time.NewTicker(tick)
defer ticker.Stop() defer ticker.Stop()
var tickC <-chan time.Time for tick := ticker.C; ; {
// Check the condition once first on the initial call.
go checkCond()
for {
select { select {
case <-timer.C: case <-timer.C:
return true return true
case <-tickC: case <-tick:
tickC = nil tick = nil
go checkCond() go func() { ch <- condition() }()
case v := <-ch: case v := <-ch:
if v { if v {
return Fail(t, "Condition satisfied", msgAndArgs...) return Fail(t, "Condition satisfied", msgAndArgs...)
} }
tickC = ticker.C tick = ticker.C
} }
} }
} }
@ -2180,12 +2100,9 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
var expectedText string var expectedText string
if target != nil { if target != nil {
expectedText = target.Error() expectedText = target.Error()
if err == nil {
return Fail(t, fmt.Sprintf("Expected error with %q in chain but got nil.", expectedText), msgAndArgs...)
}
} }
chain := buildErrorChainString(err, false) chain := buildErrorChainString(err)
return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+ return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+
"expected: %q\n"+ "expected: %q\n"+
@ -2208,7 +2125,7 @@ func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
expectedText = target.Error() expectedText = target.Error()
} }
chain := buildErrorChainString(err, false) chain := buildErrorChainString(err)
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
"found: %q\n"+ "found: %q\n"+
@ -2226,17 +2143,11 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{
return true return true
} }
expectedType := reflect.TypeOf(target).Elem().String() chain := buildErrorChainString(err)
if err == nil {
return Fail(t, fmt.Sprintf("An error is expected but got nil.\n"+
"expected: %s", expectedType), msgAndArgs...)
}
chain := buildErrorChainString(err, true)
return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ return Fail(t, fmt.Sprintf("Should be in error chain:\n"+
"expected: %s\n"+ "expected: %q\n"+
"in chain: %s", expectedType, chain, "in chain: %s", target, chain,
), msgAndArgs...) ), msgAndArgs...)
} }
@ -2250,46 +2161,24 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa
return true return true
} }
chain := buildErrorChainString(err, true) chain := buildErrorChainString(err)
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
"found: %s\n"+ "found: %q\n"+
"in chain: %s", reflect.TypeOf(target).Elem().String(), chain, "in chain: %s", target, chain,
), msgAndArgs...) ), msgAndArgs...)
} }
func unwrapAll(err error) (errs []error) { func buildErrorChainString(err error) string {
errs = append(errs, err)
switch x := err.(type) {
case interface{ Unwrap() error }:
err = x.Unwrap()
if err == nil {
return
}
errs = append(errs, unwrapAll(err)...)
case interface{ Unwrap() []error }:
for _, err := range x.Unwrap() {
errs = append(errs, unwrapAll(err)...)
}
}
return
}
func buildErrorChainString(err error, withType bool) string {
if err == nil { if err == nil {
return "" return ""
} }
var chain string e := errors.Unwrap(err)
errs := unwrapAll(err) chain := fmt.Sprintf("%q", err.Error())
for i := range errs { for e != nil {
if i != 0 { chain += fmt.Sprintf("\n\t%q", e.Error())
chain += "\n\t" e = errors.Unwrap(e)
}
chain += fmt.Sprintf("%q", errs[i].Error())
if withType {
chain += fmt.Sprintf(" (%T)", errs[i])
}
} }
return chain return chain
} }

View file

@ -1,9 +1,5 @@
// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
// //
// # Note
//
// All functions in this package return a bool value indicating whether the assertion has passed.
//
// # Example Usage // # Example Usage
// //
// The following is a complete example using assert in a standard test function: // The following is a complete example using assert in a standard test function:

View file

@ -138,7 +138,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
contains := strings.Contains(body, fmt.Sprint(str)) contains := strings.Contains(body, fmt.Sprint(str))
if !contains { if !contains {
Fail(t, fmt.Sprintf("Expected response body for %q to contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...) Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...)
} }
return contains return contains
@ -158,7 +158,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url strin
contains := strings.Contains(body, fmt.Sprint(str)) contains := strings.Contains(body, fmt.Sprint(str))
if contains { if contains {
Fail(t, fmt.Sprintf("Expected response body for %q to NOT contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...) Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...)
} }
return !contains return !contains

View file

@ -1,4 +1,5 @@
//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default //go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default
// +build testify_yaml_custom,!testify_yaml_fail,!testify_yaml_default
// Package yaml is an implementation of YAML functions that calls a pluggable implementation. // Package yaml is an implementation of YAML functions that calls a pluggable implementation.
// //

View file

@ -1,4 +1,5 @@
//go:build !testify_yaml_fail && !testify_yaml_custom //go:build !testify_yaml_fail && !testify_yaml_custom
// +build !testify_yaml_fail,!testify_yaml_custom
// Package yaml is just an indirection to handle YAML deserialization. // Package yaml is just an indirection to handle YAML deserialization.
// //

View file

@ -1,4 +1,5 @@
//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default //go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default
// +build testify_yaml_fail,!testify_yaml_custom,!testify_yaml_default
// Package yaml is an implementation of YAML functions that always fail. // Package yaml is an implementation of YAML functions that always fail.
// //

2
vendor/modules.txt vendored
View file

@ -85,7 +85,7 @@ github.com/rs/zerolog/log
# github.com/russross/blackfriday/v2 v2.1.0 # github.com/russross/blackfriday/v2 v2.1.0
## explicit ## explicit
github.com/russross/blackfriday/v2 github.com/russross/blackfriday/v2
# github.com/stretchr/testify v1.11.1 # github.com/stretchr/testify v1.10.0
## explicit; go 1.17 ## explicit; go 1.17
github.com/stretchr/testify/assert github.com/stretchr/testify/assert
github.com/stretchr/testify/assert/yaml github.com/stretchr/testify/assert/yaml