@@ -1161,6 +1161,39 @@ func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) stri
1161
1161
return msg .String ()
1162
1162
}
1163
1163
1164
+ // NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified
1165
+ // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
1166
+ // the number of appearances of each of them in both lists should not match.
1167
+ // This is an inverse of ElementsMatch.
1168
+ //
1169
+ // assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false
1170
+ //
1171
+ // assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true
1172
+ //
1173
+ // assert.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true
1174
+ func NotElementsMatch (t TestingT , listA , listB interface {}, msgAndArgs ... interface {}) (ok bool ) {
1175
+ if h , ok := t .(tHelper ); ok {
1176
+ h .Helper ()
1177
+ }
1178
+ if isEmpty (listA ) && isEmpty (listB ) {
1179
+ return Fail (t , "listA and listB contain the same elements" , msgAndArgs )
1180
+ }
1181
+
1182
+ if ! isList (t , listA , msgAndArgs ... ) {
1183
+ return Fail (t , "listA is not a list type" , msgAndArgs ... )
1184
+ }
1185
+ if ! isList (t , listB , msgAndArgs ... ) {
1186
+ return Fail (t , "listB is not a list type" , msgAndArgs ... )
1187
+ }
1188
+
1189
+ extraA , extraB := diffLists (listA , listB )
1190
+ if len (extraA ) == 0 && len (extraB ) == 0 {
1191
+ return Fail (t , "listA and listB contain the same elements" , msgAndArgs )
1192
+ }
1193
+
1194
+ return true
1195
+ }
1196
+
1164
1197
// Condition uses a Comparison to assert a complex condition.
1165
1198
func Condition (t TestingT , comp Comparison , msgAndArgs ... interface {}) bool {
1166
1199
if h , ok := t .(tHelper ); ok {
@@ -1908,6 +1941,9 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t
1908
1941
1909
1942
// CollectT implements the TestingT interface and collects all errors.
1910
1943
type CollectT struct {
1944
+ // A slice of errors. Non-nil slice denotes a failure.
1945
+ // If it's non-nil but len(c.errors) == 0, this is also a failure
1946
+ // obtained by direct c.FailNow() call.
1911
1947
errors []error
1912
1948
}
1913
1949
@@ -1916,9 +1952,10 @@ func (c *CollectT) Errorf(format string, args ...interface{}) {
1916
1952
c .errors = append (c .errors , fmt .Errorf (format , args ... ))
1917
1953
}
1918
1954
1919
- // FailNow panics.
1920
- func (* CollectT ) FailNow () {
1921
- panic ("Assertion failed" )
1955
+ // FailNow stops execution by calling runtime.Goexit.
1956
+ func (c * CollectT ) FailNow () {
1957
+ c .fail ()
1958
+ runtime .Goexit ()
1922
1959
}
1923
1960
1924
1961
// Deprecated: That was a method for internal usage that should not have been published. Now just panics.
@@ -1931,6 +1968,16 @@ func (*CollectT) Copy(TestingT) {
1931
1968
panic ("Copy() is deprecated" )
1932
1969
}
1933
1970
1971
+ func (c * CollectT ) fail () {
1972
+ if ! c .failed () {
1973
+ c .errors = []error {} // Make it non-nil to mark a failure.
1974
+ }
1975
+ }
1976
+
1977
+ func (c * CollectT ) failed () bool {
1978
+ return c .errors != nil
1979
+ }
1980
+
1934
1981
// EventuallyWithT asserts that given condition will be met in waitFor time,
1935
1982
// periodically checking target function each tick. In contrast to Eventually,
1936
1983
// it supplies a CollectT to the condition function, so that the condition
@@ -1955,7 +2002,7 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
1955
2002
}
1956
2003
1957
2004
var lastFinishedTickErrs []error
1958
- ch := make (chan [] error , 1 )
2005
+ ch := make (chan * CollectT , 1 )
1959
2006
1960
2007
timer := time .NewTimer (waitFor )
1961
2008
defer timer .Stop ()
@@ -1975,16 +2022,16 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
1975
2022
go func () {
1976
2023
collect := new (CollectT )
1977
2024
defer func () {
1978
- ch <- collect . errors
2025
+ ch <- collect
1979
2026
}()
1980
2027
condition (collect )
1981
2028
}()
1982
- case errs := <- ch :
1983
- if len ( errs ) == 0 {
2029
+ case collect := <- ch :
2030
+ if ! collect . failed () {
1984
2031
return true
1985
2032
}
1986
2033
// Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached.
1987
- lastFinishedTickErrs = errs
2034
+ lastFinishedTickErrs = collect . errors
1988
2035
tick = ticker .C
1989
2036
}
1990
2037
}
@@ -2046,7 +2093,7 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
2046
2093
), msgAndArgs ... )
2047
2094
}
2048
2095
2049
- // NotErrorIs asserts that at none of the errors in err's chain matches target.
2096
+ // NotErrorIs asserts that none of the errors in err's chain matches target.
2050
2097
// This is a wrapper for errors.Is.
2051
2098
func NotErrorIs (t TestingT , err , target error , msgAndArgs ... interface {}) bool {
2052
2099
if h , ok := t .(tHelper ); ok {
@@ -2087,6 +2134,24 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{
2087
2134
), msgAndArgs ... )
2088
2135
}
2089
2136
2137
+ // NotErrorAs asserts that none of the errors in err's chain matches target,
2138
+ // but if so, sets target to that error value.
2139
+ func NotErrorAs (t TestingT , err error , target interface {}, msgAndArgs ... interface {}) bool {
2140
+ if h , ok := t .(tHelper ); ok {
2141
+ h .Helper ()
2142
+ }
2143
+ if ! errors .As (err , target ) {
2144
+ return true
2145
+ }
2146
+
2147
+ chain := buildErrorChainString (err )
2148
+
2149
+ return Fail (t , fmt .Sprintf ("Target error should not be in err chain:\n " +
2150
+ "found: %q\n " +
2151
+ "in chain: %s" , target , chain ,
2152
+ ), msgAndArgs ... )
2153
+ }
2154
+
2090
2155
func buildErrorChainString (err error ) string {
2091
2156
if err == nil {
2092
2157
return ""
0 commit comments