From 3a702f0a2e5e2fd1976f7518ec084377138037b9 Mon Sep 17 00:00:00 2001 From: mohammad matin fotouhi Date: Fri, 5 Feb 2021 17:14:56 +0330 Subject: [PATCH 1/6] added Kind method + tests --- assert/assertions.go | 12 +++++++++++ assert/assertions_test.go | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/assert/assertions.go b/assert/assertions.go index a27e70546..efce00921 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -2313,3 +2313,15 @@ func buildErrorChainString(err error, withType bool) string { } return chain } + +// Kind check if the given object is of the given type +func Kind(t TestingT, expected reflect.Kind, object interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if reflect.TypeOf(object).Kind() == expected { + return true + } + return false +} diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 4975f5e41..d30425531 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -608,10 +608,14 @@ func TestEqual(t *testing.T) { {uint64(123), uint64(123), true, ""}, {myType("1"), myType("1"), true, ""}, {&struct{}{}, &struct{}{}, true, "pointer equality is based on equality of underlying value"}, + {time.Date(2020, 3, 1, 12, 23, 14, 0, time.UTC), time.Date(2020, 3, 1, 12, 23, 14, 0, time.UTC), true, ""}, + {time.Date(2020, 6, 3, 12, 23, 14, 0, time.UTC), time.Date(2020, 6, 3, 12, 23, 14, 0, time.UTC), true, ""}, // Not expected to be equal {m["bar"], "something", false, ""}, {myType("1"), myType("2"), false, ""}, + {time.Date(2020, 3, 1, 12, 23, 14, 0, time.UTC), time.Date(2020, 5, 1, 12, 23, 14, 0, time.UTC), true, ""}, + {time.Date(2020, 6, 3, 12, 23, 14, 0, time.UTC), time.Date(2020, 8, 3, 12, 23, 14, 0, time.UTC), true, ""}, // A case that might be confusing, especially with numeric literals {10, uint(10), false, ""}, @@ -4210,3 +4214,42 @@ func TestNotErrorAsWithErrorTooLongToPrint(t *testing.T) { in chain: "long: [0 0 0`) Contains(t, mockT.errorString(), "<... truncated>") } + +func TestKind(t *testing.T) { + type myType string + + mockT := new(testing.T) + a := 12 + + cases := []struct { + expected reflect.Kind + object interface{} + result bool + remark string + }{ + {reflect.String, "Hello World", true, "1"}, + {reflect.Int, 123, true, "2"}, + {reflect.Array, [6]int{2, 3, 5, 7, 11, 13}, true, "3"}, + {reflect.Func, Kind, true, "4"}, + {reflect.Float64, 0.0345, true, "5"}, + {reflect.Map, make(map[string]int), true, "6"}, + {reflect.Bool, true, true, "7"}, + {reflect.Ptr, &a, true, "8"}, + + // Not expected to be equal + {reflect.String, 13, false, "9"}, + {reflect.Int, [6]int{2, 3, 5, 7, 11, 13}, false, "10"}, + {reflect.Float64, 12, false, "11"}, + {reflect.Bool, make(map[string]int), false, "12"}, + } + + for _, c := range cases { + t.Run(fmt.Sprintf("Kind(%#v, %#v)", c.expected, c.object), func(t *testing.T) { + res := Kind(mockT, c.expected, c.object) + + if res != c.result { + t.Errorf("Kind(%#v, %#v) should return %#v: %s", c.expected, c.object, c.result, c.remark) + } + }) + } +} From 0e1ca6f0f058f163142d1fe6638eb5b465a2829d Mon Sep 17 00:00:00 2001 From: Henry Wibowo Date: Mon, 29 Sep 2025 09:17:40 +0700 Subject: [PATCH 2/6] Remove unrelated changes --- assert/assertions_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index d30425531..ae62c96a0 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -608,14 +608,10 @@ func TestEqual(t *testing.T) { {uint64(123), uint64(123), true, ""}, {myType("1"), myType("1"), true, ""}, {&struct{}{}, &struct{}{}, true, "pointer equality is based on equality of underlying value"}, - {time.Date(2020, 3, 1, 12, 23, 14, 0, time.UTC), time.Date(2020, 3, 1, 12, 23, 14, 0, time.UTC), true, ""}, - {time.Date(2020, 6, 3, 12, 23, 14, 0, time.UTC), time.Date(2020, 6, 3, 12, 23, 14, 0, time.UTC), true, ""}, // Not expected to be equal {m["bar"], "something", false, ""}, {myType("1"), myType("2"), false, ""}, - {time.Date(2020, 3, 1, 12, 23, 14, 0, time.UTC), time.Date(2020, 5, 1, 12, 23, 14, 0, time.UTC), true, ""}, - {time.Date(2020, 6, 3, 12, 23, 14, 0, time.UTC), time.Date(2020, 8, 3, 12, 23, 14, 0, time.UTC), true, ""}, // A case that might be confusing, especially with numeric literals {10, uint(10), false, ""}, From 0ea708d1d742734491063bca2d86e6075c6914bf Mon Sep 17 00:00:00 2001 From: Henry Wibowo Date: Mon, 29 Sep 2025 10:29:08 +0700 Subject: [PATCH 3/6] Add msgAndArgs and use Fail in Kind function Update unit test --- assert/assertions.go | 27 +++++++------- assert/assertions_test.go | 75 +++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index efce00921..7691e5d62 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -487,6 +487,21 @@ func IsNotType(t TestingT, theType, object interface{}, msgAndArgs ...interface{ return Fail(t, fmt.Sprintf("Object type expected to be different than %T", theType), msgAndArgs...) } +// Kind asserts that the given object's kind matches the expected kind. +// +// assert.Kind(t, reflect.String, "Hello World") +func Kind(t TestingT, expectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + objectKind := reflect.TypeOf(object).Kind() + if objectKind == expectedKind { + return true + } + return Fail(t, fmt.Sprintf("Object expected to be of kind %v, but was %v", expectedKind, objectKind), msgAndArgs...) +} + // Equal asserts that two objects are equal. // // assert.Equal(t, 123, 123) @@ -2313,15 +2328,3 @@ func buildErrorChainString(err error, withType bool) string { } return chain } - -// Kind check if the given object is of the given type -func Kind(t TestingT, expected reflect.Kind, object interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if reflect.TypeOf(object).Kind() == expected { - return true - } - return false -} diff --git a/assert/assertions_test.go b/assert/assertions_test.go index ae62c96a0..6b805e522 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -585,6 +585,42 @@ func TestNotIsType(t *testing.T) { } } +func TestKind(t *testing.T) { + mockT := new(testing.T) + + cases := []struct { + expected reflect.Kind + object interface{} + result bool + remark string + }{ + {reflect.String, "Hello World", true, "1"}, + {reflect.Int, 123, true, "2"}, + {reflect.Array, [6]int{2, 3, 5, 7, 11, 13}, true, "3"}, + {reflect.Func, Kind, true, "4"}, + {reflect.Float64, 0.0345, true, "5"}, + {reflect.Map, make(map[string]int), true, "6"}, + {reflect.Bool, true, true, "7"}, + {reflect.Ptr, new(int), true, "8"}, + + // Not expected to be equal + {reflect.String, 13, false, "9"}, + {reflect.Int, [6]int{2, 3, 5, 7, 11, 13}, false, "10"}, + {reflect.Float64, 12, false, "11"}, + {reflect.Bool, make(map[string]int), false, "12"}, + } + + for _, c := range cases { + t.Run(fmt.Sprintf("Kind(%#v, %#v)", c.expected, c.object), func(t *testing.T) { + res := Kind(mockT, c.expected, c.object) + + if res != c.result { + t.Errorf("Kind(%#v, %#v) should return %#v: %s", c.expected, c.object, c.result, c.remark) + } + }) + } +} + func TestEqual(t *testing.T) { t.Parallel() @@ -4210,42 +4246,3 @@ func TestNotErrorAsWithErrorTooLongToPrint(t *testing.T) { in chain: "long: [0 0 0`) Contains(t, mockT.errorString(), "<... truncated>") } - -func TestKind(t *testing.T) { - type myType string - - mockT := new(testing.T) - a := 12 - - cases := []struct { - expected reflect.Kind - object interface{} - result bool - remark string - }{ - {reflect.String, "Hello World", true, "1"}, - {reflect.Int, 123, true, "2"}, - {reflect.Array, [6]int{2, 3, 5, 7, 11, 13}, true, "3"}, - {reflect.Func, Kind, true, "4"}, - {reflect.Float64, 0.0345, true, "5"}, - {reflect.Map, make(map[string]int), true, "6"}, - {reflect.Bool, true, true, "7"}, - {reflect.Ptr, &a, true, "8"}, - - // Not expected to be equal - {reflect.String, 13, false, "9"}, - {reflect.Int, [6]int{2, 3, 5, 7, 11, 13}, false, "10"}, - {reflect.Float64, 12, false, "11"}, - {reflect.Bool, make(map[string]int), false, "12"}, - } - - for _, c := range cases { - t.Run(fmt.Sprintf("Kind(%#v, %#v)", c.expected, c.object), func(t *testing.T) { - res := Kind(mockT, c.expected, c.object) - - if res != c.result { - t.Errorf("Kind(%#v, %#v) should return %#v: %s", c.expected, c.object, c.result, c.remark) - } - }) - } -} From f7231ccd55212c6e8b95fd78f4bd19b9d019c756 Mon Sep 17 00:00:00 2001 From: Henry Wibowo Date: Mon, 29 Sep 2025 10:41:28 +0700 Subject: [PATCH 4/6] Add NotKind function --- assert/assertions.go | 15 +++++++++++ assert/assertions_test.go | 53 ++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index 7691e5d62..d5fe59ed5 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -502,6 +502,21 @@ func Kind(t TestingT, expectedKind reflect.Kind, object interface{}, msgAndArgs return Fail(t, fmt.Sprintf("Object expected to be of kind %v, but was %v", expectedKind, objectKind), msgAndArgs...) } +// NotKind asserts that the given object's kind does not match the unexpected kind. +// +// assert.NotKind(t, reflect.Int, "Hello World") +func NotKind(t TestingT, unexpectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + objectKind := reflect.TypeOf(object).Kind() + if objectKind != unexpectedKind { + return true + } + return Fail(t, fmt.Sprintf("Object expected NOT to be of kind %v, but was %v", unexpectedKind, objectKind), msgAndArgs...) +} + // Equal asserts that two objects are equal. // // assert.Equal(t, 123, 123) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 6b805e522..4b82f99fd 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -594,20 +594,20 @@ func TestKind(t *testing.T) { result bool remark string }{ - {reflect.String, "Hello World", true, "1"}, - {reflect.Int, 123, true, "2"}, - {reflect.Array, [6]int{2, 3, 5, 7, 11, 13}, true, "3"}, - {reflect.Func, Kind, true, "4"}, - {reflect.Float64, 0.0345, true, "5"}, - {reflect.Map, make(map[string]int), true, "6"}, - {reflect.Bool, true, true, "7"}, - {reflect.Ptr, new(int), true, "8"}, + {reflect.String, "Hello World", true, "is string"}, + {reflect.Int, 123, true, "is int"}, + {reflect.Array, [6]int{2, 3, 5, 7, 11, 13}, true, "is array"}, + {reflect.Func, Kind, true, "is func"}, + {reflect.Float64, 0.0345, true, "is float64"}, + {reflect.Map, make(map[string]int), true, "is map"}, + {reflect.Bool, true, true, "is bool"}, + {reflect.Ptr, new(int), true, "is pointer"}, // Not expected to be equal - {reflect.String, 13, false, "9"}, - {reflect.Int, [6]int{2, 3, 5, 7, 11, 13}, false, "10"}, - {reflect.Float64, 12, false, "11"}, - {reflect.Bool, make(map[string]int), false, "12"}, + {reflect.String, 13, false, "not string"}, + {reflect.Int, [6]int{2, 3, 5, 7, 11, 13}, false, "not int"}, + {reflect.Float64, 12, false, "not float64"}, + {reflect.Bool, make(map[string]int), false, "not bool"}, } for _, c := range cases { @@ -621,6 +621,35 @@ func TestKind(t *testing.T) { } } +func TestNotKind(t *testing.T) { + mockT := new(testing.T) + + cases := []struct { + unexpected reflect.Kind + object interface{} + result bool + remark string + }{ + {reflect.String, 123, true, "not string"}, + {reflect.Int, "hi", true, "not int"}, + {reflect.Map, []int{1, 2}, true, "not map"}, + {reflect.Ptr, 99, true, "not pointer"}, + + // Should fail when kinds match + {reflect.Func, func() {}, false, "is func"}, + {reflect.Bool, false, false, "is bool"}, + } + + for _, c := range cases { + t.Run(fmt.Sprintf("NotKind(%#v, %#v)", c.unexpected, c.object), func(t *testing.T) { + res := NotKind(mockT, c.unexpected, c.object) + if res != c.result { + t.Errorf("NotKind(%#v, %#v) should return %#v: %s", c.unexpected, c.object, c.result, c.remark) + } + }) + } +} + func TestEqual(t *testing.T) { t.Parallel() From 8b7c2e07e02989139db2a3e56d85ed50b9955b53 Mon Sep 17 00:00:00 2001 From: Henry Wibowo Date: Mon, 29 Sep 2025 10:54:20 +0700 Subject: [PATCH 5/6] Run go generate --- assert/assertion_format.go | 21 +++++++++++++++ assert/assertion_forward.go | 41 ++++++++++++++++++++++++++++ require/require.go | 53 +++++++++++++++++++++++++++++++++++++ require/require_forward.go | 41 ++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 2d089991a..e88203538 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -5,6 +5,7 @@ package assert import ( http "net/http" url "net/url" + reflect "reflect" time "time" ) @@ -475,6 +476,16 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...) } +// Kindf asserts that the given object's kind matches the expected kind. +// +// assert.Kindf(t, reflect.String, "Hello World", "error message %s", "formatted") +func Kindf(t TestingT, expectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Kind(t, expectedKind, object, append([]interface{}{msg}, args...)...) +} + // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // @@ -667,6 +678,16 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, return NotImplements(t, interfaceObject, object, append([]interface{}{msg}, args...)...) } +// NotKindf asserts that the given object's kind does not match the unexpected kind. +// +// assert.NotKindf(t, reflect.Int, "Hello World", "error message %s", "formatted") +func NotKindf(t TestingT, unexpectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotKind(t, unexpectedKind, object, append([]interface{}{msg}, args...)...) +} + // NotNilf asserts that the specified object is not nil. // // assert.NotNilf(t, err, "error message %s", "formatted") diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index d8300af73..f36db4721 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -5,6 +5,7 @@ package assert import ( http "net/http" url "net/url" + reflect "reflect" time "time" ) @@ -942,6 +943,26 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args .. return JSONEqf(a.t, expected, actual, msg, args...) } +// Kind asserts that the given object's kind matches the expected kind. +// +// a.Kind(reflect.String, "Hello World") +func (a *Assertions) Kind(expectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Kind(a.t, expectedKind, object, msgAndArgs...) +} + +// Kindf asserts that the given object's kind matches the expected kind. +// +// a.Kindf(reflect.String, "Hello World", "error message %s", "formatted") +func (a *Assertions) Kindf(expectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Kindf(a.t, expectedKind, object, msg, args...) +} + // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // @@ -1326,6 +1347,26 @@ func (a *Assertions) NotImplementsf(interfaceObject interface{}, object interfac return NotImplementsf(a.t, interfaceObject, object, msg, args...) } +// NotKind asserts that the given object's kind does not match the unexpected kind. +// +// a.NotKind(reflect.Int, "Hello World") +func (a *Assertions) NotKind(unexpectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotKind(a.t, unexpectedKind, object, msgAndArgs...) +} + +// NotKindf asserts that the given object's kind does not match the unexpected kind. +// +// a.NotKindf(reflect.Int, "Hello World", "error message %s", "formatted") +func (a *Assertions) NotKindf(unexpectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotKindf(a.t, unexpectedKind, object, msg, args...) +} + // NotNil asserts that the specified object is not nil. // // a.NotNil(err) diff --git a/require/require.go b/require/require.go index 23a3be780..59a29d7da 100644 --- a/require/require.go +++ b/require/require.go @@ -6,6 +6,7 @@ import ( assert "github.com/stretchr/testify/assert" http "net/http" url "net/url" + reflect "reflect" time "time" ) @@ -1189,6 +1190,32 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int t.FailNow() } +// Kind asserts that the given object's kind matches the expected kind. +// +// require.Kind(t, reflect.String, "Hello World") +func Kind(t TestingT, expectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.Kind(t, expectedKind, object, msgAndArgs...) { + return + } + t.FailNow() +} + +// Kindf asserts that the given object's kind matches the expected kind. +// +// require.Kindf(t, reflect.String, "Hello World", "error message %s", "formatted") +func Kindf(t TestingT, expectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.Kindf(t, expectedKind, object, msg, args...) { + return + } + t.FailNow() +} + // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // @@ -1675,6 +1702,32 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, t.FailNow() } +// NotKind asserts that the given object's kind does not match the unexpected kind. +// +// require.NotKind(t, reflect.Int, "Hello World") +func NotKind(t TestingT, unexpectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotKind(t, unexpectedKind, object, msgAndArgs...) { + return + } + t.FailNow() +} + +// NotKindf asserts that the given object's kind does not match the unexpected kind. +// +// require.NotKindf(t, reflect.Int, "Hello World", "error message %s", "formatted") +func NotKindf(t TestingT, unexpectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotKindf(t, unexpectedKind, object, msg, args...) { + return + } + t.FailNow() +} + // NotNil asserts that the specified object is not nil. // // require.NotNil(t, err) diff --git a/require/require_forward.go b/require/require_forward.go index 38d985a55..819d5c8ae 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -6,6 +6,7 @@ import ( assert "github.com/stretchr/testify/assert" http "net/http" url "net/url" + reflect "reflect" time "time" ) @@ -943,6 +944,26 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args .. JSONEqf(a.t, expected, actual, msg, args...) } +// Kind asserts that the given object's kind matches the expected kind. +// +// a.Kind(reflect.String, "Hello World") +func (a *Assertions) Kind(expectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + Kind(a.t, expectedKind, object, msgAndArgs...) +} + +// Kindf asserts that the given object's kind matches the expected kind. +// +// a.Kindf(reflect.String, "Hello World", "error message %s", "formatted") +func (a *Assertions) Kindf(expectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + Kindf(a.t, expectedKind, object, msg, args...) +} + // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // @@ -1327,6 +1348,26 @@ func (a *Assertions) NotImplementsf(interfaceObject interface{}, object interfac NotImplementsf(a.t, interfaceObject, object, msg, args...) } +// NotKind asserts that the given object's kind does not match the unexpected kind. +// +// a.NotKind(reflect.Int, "Hello World") +func (a *Assertions) NotKind(unexpectedKind reflect.Kind, object interface{}, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotKind(a.t, unexpectedKind, object, msgAndArgs...) +} + +// NotKindf asserts that the given object's kind does not match the unexpected kind. +// +// a.NotKindf(reflect.Int, "Hello World", "error message %s", "formatted") +func (a *Assertions) NotKindf(unexpectedKind reflect.Kind, object interface{}, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotKindf(a.t, unexpectedKind, object, msg, args...) +} + // NotNil asserts that the specified object is not nil. // // a.NotNil(err) From efa51f81044d45fee3ce7f61c53bc0484cb149b9 Mon Sep 17 00:00:00 2001 From: Henry Wibowo Date: Tue, 21 Oct 2025 20:48:47 +0700 Subject: [PATCH 6/6] Handle reflect invalid and nil cases --- assert/assertions.go | 18 ++++++++++++++++++ assert/assertions_test.go | 14 ++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/assert/assertions.go b/assert/assertions.go index d5fe59ed5..d08ef2a89 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -495,10 +495,19 @@ func Kind(t TestingT, expectedKind reflect.Kind, object interface{}, msgAndArgs h.Helper() } + if expectedKind == reflect.Invalid { + return Fail(t, "reflect.Invalid must not be used as expected kind", msgAndArgs...) + } + + if object == nil { + return Fail(t, "Object must not be nil", msgAndArgs...) + } + objectKind := reflect.TypeOf(object).Kind() if objectKind == expectedKind { return true } + return Fail(t, fmt.Sprintf("Object expected to be of kind %v, but was %v", expectedKind, objectKind), msgAndArgs...) } @@ -510,10 +519,19 @@ func NotKind(t TestingT, unexpectedKind reflect.Kind, object interface{}, msgAnd h.Helper() } + if unexpectedKind == reflect.Invalid { + return Fail(t, "reflect.Invalid must not be used as unexpected kind", msgAndArgs...) + } + + if object == nil { + return Fail(t, "Object must not be nil", msgAndArgs...) + } + objectKind := reflect.TypeOf(object).Kind() if objectKind != unexpectedKind { return true } + return Fail(t, fmt.Sprintf("Object expected NOT to be of kind %v, but was %v", unexpectedKind, objectKind), msgAndArgs...) } diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 4b82f99fd..2f9bf5316 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -594,6 +594,7 @@ func TestKind(t *testing.T) { result bool remark string }{ + // True cases {reflect.String, "Hello World", true, "is string"}, {reflect.Int, 123, true, "is int"}, {reflect.Array, [6]int{2, 3, 5, 7, 11, 13}, true, "is array"}, @@ -603,11 +604,15 @@ func TestKind(t *testing.T) { {reflect.Bool, true, true, "is bool"}, {reflect.Ptr, new(int), true, "is pointer"}, - // Not expected to be equal + // False cases {reflect.String, 13, false, "not string"}, {reflect.Int, [6]int{2, 3, 5, 7, 11, 13}, false, "not int"}, {reflect.Float64, 12, false, "not float64"}, {reflect.Bool, make(map[string]int), false, "not bool"}, + + // Invalid inputs + {reflect.Invalid, "string", false, "reflect.Invalid must not be used as expected kind"}, + {reflect.Ptr, nil, false, "Object must not be nil"}, } for _, c := range cases { @@ -630,14 +635,19 @@ func TestNotKind(t *testing.T) { result bool remark string }{ + // True cases {reflect.String, 123, true, "not string"}, {reflect.Int, "hi", true, "not int"}, {reflect.Map, []int{1, 2}, true, "not map"}, {reflect.Ptr, 99, true, "not pointer"}, - // Should fail when kinds match + // False cases {reflect.Func, func() {}, false, "is func"}, {reflect.Bool, false, false, "is bool"}, + + // Invalid inputs + {reflect.Invalid, "string", false, "reflect.Invalid must not be used as unexpected kind"}, + {reflect.Ptr, nil, false, "Object must not be nil"}, } for _, c := range cases {