mirror of
https://github.com/stretchr/testify.git
synced 2025-05-31 11:42:44 +00:00
assert.Empty: comprehensive doc of "Empty"-ness rules
Document the assert.Empty rules more comprehensively. This exposes our quirks to the user to avoid wrong expectations. Add many many many more test cases that document edges cases and will allow to catch breaking changes and avoid regressions.
This commit is contained in:
parent
0ff4bb43de
commit
6485e376c5
@ -50,10 +50,19 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
|
||||
return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [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")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -595,8 +604,7 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str
|
||||
return NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
|
@ -92,10 +92,19 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
|
||||
return ElementsMatchf(a.t, listA, listB, msg, args...)
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [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)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -103,10 +112,19 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return Empty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [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")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -1182,8 +1200,7 @@ func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg
|
||||
return NotElementsMatchf(a.t, listA, listB, msg, args...)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmpty(obj) {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@ -1195,8 +1212,7 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo
|
||||
return NotEmpty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmptyf(obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
|
@ -773,10 +773,19 @@ func isEmpty(object interface{}) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [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)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
pass := isEmpty(object)
|
||||
if !pass {
|
||||
@ -789,8 +798,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return pass
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if assert.NotEmpty(t, obj) {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
|
@ -1728,24 +1728,119 @@ func Test_isEmpty(t *testing.T) {
|
||||
|
||||
True(t, isEmpty(""))
|
||||
True(t, isEmpty(nil))
|
||||
True(t, isEmpty(error(nil)))
|
||||
True(t, isEmpty((*int)(nil)))
|
||||
True(t, isEmpty((*string)(nil)))
|
||||
True(t, isEmpty(new(string)))
|
||||
True(t, isEmpty([]string{}))
|
||||
True(t, isEmpty([]string(nil)))
|
||||
True(t, isEmpty([]byte(nil)))
|
||||
True(t, isEmpty([]byte{}))
|
||||
True(t, isEmpty([]byte("")))
|
||||
True(t, isEmpty([]bool(nil)))
|
||||
True(t, isEmpty([]bool{}))
|
||||
True(t, isEmpty([]interface{}(nil)))
|
||||
True(t, isEmpty([]interface{}{}))
|
||||
True(t, isEmpty(struct{}{}))
|
||||
True(t, isEmpty(&struct{}{}))
|
||||
True(t, isEmpty(struct{ A int }{A: 0}))
|
||||
True(t, isEmpty(struct{ a int }{a: 0}))
|
||||
True(t, isEmpty(struct {
|
||||
a int
|
||||
B int
|
||||
}{a: 0, B: 0}))
|
||||
True(t, isEmpty(0))
|
||||
True(t, isEmpty(int(0)))
|
||||
True(t, isEmpty(int8(0)))
|
||||
True(t, isEmpty(int16(0)))
|
||||
True(t, isEmpty(uint16(0)))
|
||||
True(t, isEmpty(int32(0)))
|
||||
True(t, isEmpty(uint32(0)))
|
||||
True(t, isEmpty(int64(0)))
|
||||
True(t, isEmpty(uint64(0)))
|
||||
True(t, isEmpty('\u0000')) // rune => int32
|
||||
True(t, isEmpty(float32(0)))
|
||||
True(t, isEmpty(float64(0)))
|
||||
True(t, isEmpty(0i)) // complex
|
||||
True(t, isEmpty(0.0i)) // complex
|
||||
True(t, isEmpty(false))
|
||||
True(t, isEmpty(new(bool)))
|
||||
True(t, isEmpty(map[string]string{}))
|
||||
True(t, isEmpty(map[string]string(nil)))
|
||||
True(t, isEmpty(new(time.Time)))
|
||||
True(t, isEmpty(time.Time{}))
|
||||
True(t, isEmpty(make(chan struct{})))
|
||||
True(t, isEmpty([1]int{}))
|
||||
True(t, isEmpty(chan struct{}(nil)))
|
||||
True(t, isEmpty(chan<- struct{}(nil)))
|
||||
True(t, isEmpty(make(chan struct{})))
|
||||
True(t, isEmpty(make(chan<- struct{})))
|
||||
True(t, isEmpty(make(chan struct{}, 1)))
|
||||
True(t, isEmpty(make(chan<- struct{}, 1)))
|
||||
True(t, isEmpty([1]int{0}))
|
||||
True(t, isEmpty([2]int{0, 0}))
|
||||
True(t, isEmpty([8]int{}))
|
||||
True(t, isEmpty([...]int{7: 0}))
|
||||
True(t, isEmpty([...]bool{false, false}))
|
||||
True(t, isEmpty(errors.New(""))) // BEWARE
|
||||
True(t, isEmpty([]error{}))
|
||||
True(t, isEmpty([]error(nil)))
|
||||
True(t, isEmpty(&[1]int{0}))
|
||||
True(t, isEmpty(&[2]int{0, 0}))
|
||||
False(t, isEmpty("something"))
|
||||
False(t, isEmpty(errors.New("something")))
|
||||
False(t, isEmpty([]string{"something"}))
|
||||
False(t, isEmpty(1))
|
||||
False(t, isEmpty(int(1)))
|
||||
False(t, isEmpty(uint(1)))
|
||||
False(t, isEmpty(byte(1)))
|
||||
False(t, isEmpty(int8(1)))
|
||||
False(t, isEmpty(uint8(1)))
|
||||
False(t, isEmpty(int16(1)))
|
||||
False(t, isEmpty(uint16(1)))
|
||||
False(t, isEmpty(int32(1)))
|
||||
False(t, isEmpty(uint32(1)))
|
||||
False(t, isEmpty(int64(1)))
|
||||
False(t, isEmpty(uint64(1)))
|
||||
False(t, isEmpty('A')) // rune => int32
|
||||
False(t, isEmpty(true))
|
||||
False(t, isEmpty(1.0))
|
||||
False(t, isEmpty(1i)) // complex
|
||||
False(t, isEmpty([]byte{0})) // elements values are ignored for slices
|
||||
False(t, isEmpty([]byte{0, 0})) // elements values are ignored for slices
|
||||
False(t, isEmpty([]string{""})) // elements values are ignored for slices
|
||||
False(t, isEmpty([]string{"a"})) // elements values are ignored for slices
|
||||
False(t, isEmpty([]bool{false})) // elements values are ignored for slices
|
||||
False(t, isEmpty([]bool{true})) // elements values are ignored for slices
|
||||
False(t, isEmpty([]error{errors.New("xxx")}))
|
||||
False(t, isEmpty([]error{nil})) // BEWARE
|
||||
False(t, isEmpty([]error{errors.New("")})) // BEWARE
|
||||
False(t, isEmpty(map[string]string{"Hello": "World"}))
|
||||
False(t, isEmpty(map[string]string{"": ""}))
|
||||
False(t, isEmpty(map[string]string{"foo": ""}))
|
||||
False(t, isEmpty(map[string]string{"": "foo"}))
|
||||
False(t, isEmpty(chWithValue))
|
||||
False(t, isEmpty([1]bool{true}))
|
||||
False(t, isEmpty([2]bool{false, true}))
|
||||
False(t, isEmpty([...]bool{10: true}))
|
||||
False(t, isEmpty([]int{0}))
|
||||
False(t, isEmpty([]int{42}))
|
||||
False(t, isEmpty([1]int{42}))
|
||||
False(t, isEmpty([2]int{0, 42}))
|
||||
False(t, isEmpty(&[1]int{42}))
|
||||
False(t, isEmpty(&[2]int{0, 42}))
|
||||
False(t, isEmpty([1]*int{new(int)})) // array elements must be the zero value, not any Empty value
|
||||
False(t, isEmpty(struct{ A int }{A: 42}))
|
||||
False(t, isEmpty(struct{ a int }{a: 42}))
|
||||
False(t, isEmpty(struct{ a *int }{a: new(int)})) // fields must be the zero value, not any Empty value
|
||||
False(t, isEmpty(struct{ a []int }{a: []int{}})) // fields must be the zero value, not any Empty value
|
||||
False(t, isEmpty(struct {
|
||||
a int
|
||||
B int
|
||||
}{a: 0, B: 42}))
|
||||
False(t, isEmpty(struct {
|
||||
a int
|
||||
B int
|
||||
}{a: 42, B: 0}))
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
|
@ -117,10 +117,19 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [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".
|
||||
//
|
||||
// require.Empty(t, obj)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -131,10 +140,19 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [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".
|
||||
//
|
||||
// require.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{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -1495,8 +1513,7 @@ func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg str
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if require.NotEmpty(t, obj) {
|
||||
// require.Equal(t, "two", obj[1])
|
||||
@ -1511,8 +1528,7 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if require.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// require.Equal(t, "two", obj[1])
|
||||
|
@ -93,10 +93,19 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
|
||||
ElementsMatchf(a.t, listA, listB, msg, args...)
|
||||
}
|
||||
|
||||
// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Empty asserts that the given value is "empty".
|
||||
//
|
||||
// [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)
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -104,10 +113,19 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
|
||||
Empty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
//
|
||||
// [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")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -1183,8 +1201,7 @@ func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg
|
||||
NotElementsMatchf(a.t, listA, listB, msg, args...)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmpty asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmpty(obj) {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
@ -1196,8 +1213,7 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
|
||||
NotEmpty(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if a.NotEmptyf(obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
|
Loading…
x
Reference in New Issue
Block a user