From 8c9f476f57649be9d6ae9dc53676ee14b2621865 Mon Sep 17 00:00:00 2001 From: Bart Venter Date: Fri, 25 Apr 2025 11:16:23 +0000 Subject: [PATCH 1/4] Add IsNotType assertion This commit introduces the `IsNotType` assertion, which is the inverse of the existing `IsType` assertion. It allows users to assert that an object is not of a specific type. Additionally, minor documentation improvements were made. --- assert/assertion_format.go | 12 +++++++++++ assert/assertion_forward.go | 24 ++++++++++++++++++++++ assert/assertions.go | 27 ++++++++++++++++++++----- assert/assertions_test.go | 12 +++++++++++ require/forward_requirements_test.go | 12 +++++++++++ require/require.go | 30 ++++++++++++++++++++++++++++ require/require_forward.go | 24 ++++++++++++++++++++++ 7 files changed, 136 insertions(+), 5 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 190634165..1f71af2e1 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -438,7 +438,19 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf 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. +// +// assert.IsTypeff(t, &MyStruct{}, &MyStruct{}) func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 21629087b..718180088 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -868,7 +868,29 @@ func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...in 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. +// +// assert.IsTypef(t, &MyStruct{}, &MyStruct{}) func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -877,6 +899,8 @@ func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAnd } // IsTypef asserts that the specified objects are of the same type. +// +// assert.IsTypeff(t, &MyStruct{}, &MyStruct{}) func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/assert/assertions.go b/assert/assertions.go index 09feff854..c886b3e8f 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -455,17 +455,34 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, 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. -func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { +// +// assert.IsTypef(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 { h.Helper() } + return Fail(t, fmt.Sprintf("Object expected to be of type %T, but was %T", expectedType, object), msgAndArgs...) +} - if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { - 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. +// +// assert.IsNotType(t, &NotMyStruct{}, &MyStruct{}) +func IsNotType(t TestingT, theType, object interface{}, msgAndArgs ...interface{}) bool { + if !isType(theType, object) { + return true } - - return true + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, fmt.Sprintf("Object expected to not be of type %T, but was %T", theType, object), msgAndArgs...) } // Equal asserts that two objects are equal. diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 9d27d1bfa..4cce806d0 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -564,6 +564,18 @@ func TestIsType(t *testing.T) { } +func TestNotIsType(t *testing.T) { + + mockT := new(testing.T) + + if !IsNotType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) { + t.Error("NotIsType should return true: AssertionTesterConformingObject is not the same type as AssertionTesterNonConformingObject") + } + if IsNotType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) { + t.Error("NotIsType should return false: AssertionTesterConformingObject is the same type as AssertionTesterConformingObject") + } +} + func TestEqual(t *testing.T) { type myType string diff --git a/require/forward_requirements_test.go b/require/forward_requirements_test.go index 8fbcc1530..99515daa3 100644 --- a/require/forward_requirements_test.go +++ b/require/forward_requirements_test.go @@ -19,6 +19,18 @@ func TestImplementsWrapper(t *testing.T) { } } +func TestIsNotTypeWrapper(t *testing.T) { + require := New(t) + require.IsNotType(new(AssertionTesterNonConformingObject), new(AssertionTesterConformingObject)) + + mockT := new(MockT) + mockRequire := New(mockT) + mockRequire.IsNotType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) + if !mockT.Failed { + t.Error("Check should fail") + } +} + func TestIsTypeWrapper(t *testing.T) { require := New(t) require.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) diff --git a/require/require.go b/require/require.go index d8921950d..4f909e87b 100644 --- a/require/require.go +++ b/require/require.go @@ -1097,7 +1097,35 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf t.FailNow() } +// IsNotType asserts that the specified objects are not of the same type. +// +// require.IsNotType(t, &NotMyStruct{}, &MyStruct{}) +func IsNotType(t TestingT, theType interface{}, object interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.IsNotType(t, theType, object, msgAndArgs...) { + return + } + t.FailNow() +} + +// IsNotTypef asserts that the specified objects are not of the same type. +// +// require.IsNotTypef(t, &NotMyStruct{}, &MyStruct{}, "error message %s", "formatted") +func IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.IsNotTypef(t, theType, object, msg, args...) { + return + } + t.FailNow() +} + // IsType asserts that the specified objects are of the same type. +// +// require.IsTypef(t, &MyStruct{}, &MyStruct{}) func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1109,6 +1137,8 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs } // IsTypef asserts that the specified objects are of the same type. +// +// require.IsTypeff(t, &MyStruct{}, &MyStruct{}) func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require_forward.go b/require/require_forward.go index 1bd87304f..82b7aba25 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -869,7 +869,29 @@ func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...in 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{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + 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{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + IsNotTypef(a.t, theType, object, msg, args...) +} + // IsType asserts that the specified objects are of the same type. +// +// assert.IsTypef(t, &MyStruct{}, &MyStruct{}) func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -878,6 +900,8 @@ func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAnd } // IsTypef asserts that the specified objects are of the same type. +// +// assert.IsTypeff(t, &MyStruct{}, &MyStruct{}) func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() From deda1e6854ee377a19c86933a4b43cf54f4affb3 Mon Sep 17 00:00:00 2001 From: Bart Venter Date: Fri, 25 Apr 2025 12:23:34 +0000 Subject: [PATCH 2/4] fix(assert): Correct typo in source file for `IsType` This commit fixes a typo in the IsType source file, which caused incorrect behavior in the generated files for the `assert` and `require` packages. --- assert/assertions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assert/assertions.go b/assert/assertions.go index c886b3e8f..8b42ec9c4 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -461,7 +461,7 @@ func isType(expectedType, object interface{}) bool { // IsType asserts that the specified objects are of the same type. // -// assert.IsTypef(t, &MyStruct{}, &MyStruct{}) +// assert.IsType(t, &MyStruct{}, &MyStruct{}) func IsType(t TestingT, expectedType, object interface{}, msgAndArgs ...interface{}) bool { if isType(expectedType, object) { return true From 15d6997d8db9d3e866b36e39ce66123cf2d590bb Mon Sep 17 00:00:00 2001 From: Bart Venter Date: Fri, 25 Apr 2025 12:26:21 +0000 Subject: [PATCH 3/4] chore(assert): Update generated files after fixing typo This commit updates the generated files in the `assert` and `require` packages to reflect the changes made in the source file for `IsType`. --- assert/assertion_format.go | 2 +- assert/assertion_forward.go | 4 ++-- require/require.go | 4 ++-- require/require_forward.go | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/assert/assertion_format.go b/assert/assertion_format.go index 1f71af2e1..e24b0d0ad 100644 --- a/assert/assertion_format.go +++ b/assert/assertion_format.go @@ -450,7 +450,7 @@ func IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, // IsTypef asserts that the specified objects are of the same type. // -// assert.IsTypeff(t, &MyStruct{}, &MyStruct{}) +// assert.IsTypef(t, &MyStruct{}, &MyStruct{}, "error message %s", "formatted") func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go index 718180088..ccd60370b 100644 --- a/assert/assertion_forward.go +++ b/assert/assertion_forward.go @@ -890,7 +890,7 @@ func (a *Assertions) IsNotTypef(theType interface{}, object interface{}, msg str // IsType asserts that the specified objects are of the same type. // -// assert.IsTypef(t, &MyStruct{}, &MyStruct{}) +// a.IsType(&MyStruct{}, &MyStruct{}) func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -900,7 +900,7 @@ func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAnd // IsTypef asserts that the specified objects are of the same type. // -// assert.IsTypeff(t, &MyStruct{}, &MyStruct{}) +// a.IsTypef(&MyStruct{}, &MyStruct{}, "error message %s", "formatted") func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/require/require.go b/require/require.go index 4f909e87b..2fc2ab5ba 100644 --- a/require/require.go +++ b/require/require.go @@ -1125,7 +1125,7 @@ func IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, // IsType asserts that the specified objects are of the same type. // -// require.IsTypef(t, &MyStruct{}, &MyStruct{}) +// require.IsType(t, &MyStruct{}, &MyStruct{}) func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1138,7 +1138,7 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs // IsTypef asserts that the specified objects are of the same type. // -// require.IsTypeff(t, &MyStruct{}, &MyStruct{}) +// require.IsTypef(t, &MyStruct{}, &MyStruct{}, "error message %s", "formatted") func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/require/require_forward.go b/require/require_forward.go index 82b7aba25..ae2e134d6 100644 --- a/require/require_forward.go +++ b/require/require_forward.go @@ -891,7 +891,7 @@ func (a *Assertions) IsNotTypef(theType interface{}, object interface{}, msg str // IsType asserts that the specified objects are of the same type. // -// assert.IsTypef(t, &MyStruct{}, &MyStruct{}) +// a.IsType(&MyStruct{}, &MyStruct{}) func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -901,7 +901,7 @@ func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAnd // IsTypef asserts that the specified objects are of the same type. // -// assert.IsTypeff(t, &MyStruct{}, &MyStruct{}) +// a.IsTypef(&MyStruct{}, &MyStruct{}, "error message %s", "formatted") func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() From 941eaaa16ae592dead1a5c3aaca727693b8f52c4 Mon Sep 17 00:00:00 2001 From: Bart Venter Date: Fri, 25 Apr 2025 13:56:46 +0000 Subject: [PATCH 4/4] refactor: improve `IsNotType` failure message for clarity Simplified the failure message in `IsNotType` to avoid redundancy and improve clarity. --- assert/assertions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assert/assertions.go b/assert/assertions.go index 8b42ec9c4..94ef819a1 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -482,7 +482,7 @@ func IsNotType(t TestingT, theType, object interface{}, msgAndArgs ...interface{ if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Object expected to not be of type %T, but was %T", theType, object), msgAndArgs...) + return Fail(t, fmt.Sprintf("Object type expected to be different than %T", theType), msgAndArgs...) } // Equal asserts that two objects are equal.