Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

Commit

Permalink
Update invariants_test.go for new HasType impl
Browse files Browse the repository at this point in the history
  • Loading branch information
varungandhi-src committed Jun 2, 2024
1 parent 50b67c0 commit a1c27a7
Showing 1 changed file with 20 additions and 64 deletions.
84 changes: 20 additions & 64 deletions lib/errors/invariants_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,23 @@ func TestInvariants(t *testing.T) {
rapid.Just(error(&notTheErrorOfInterest{})),
rapid.Just(error(payloadLessStructError{})),
)).Draw(t, "err")
// Is implies As for errors without data
// Is implies HasType and As for errors without data
if Is(err, payloadLessStructError{}) {
// This can be false, see Counter-example 1
//require.True(t, HasType(err, payloadLessStructError{}))
require.True(t, HasType[payloadLessStructError](err))
var check payloadLessStructError
require.True(t, As(err, &check))
}
// HasType implies Is and As for errors without data
if HasType(err, payloadLessStructError{}) {
if HasType[payloadLessStructError](err) {
require.True(t, Is(err, payloadLessStructError{}))
var check payloadLessStructError
require.True(t, As(err, &check))
}
var check payloadLessStructError
// As implies Is for errors without data
// As implies Is and HasType for errors without data
if As(err, &check) {
require.True(t, Is(err, payloadLessStructError{}))
// This can be false, see Counter-example 2
//require.True(t, HasType(err, payloadLessStructError{}))
require.True(t, HasType[payloadLessStructError](err))
}
})
})
Expand All @@ -70,42 +68,32 @@ func TestInvariants(t *testing.T) {
rapid.Just(error(errorWithOtherData)),
)).Draw(t, "err")

// Is implies As for errors with data
// Is implies HasType and As for errors with data
if Is(err, errorOfInterest) {
// This is false, see Counter-example 5
//require.False(t, Is(err, errorWithOtherData))
require.False(t, Is(err, withPayloadStructError{}))
// These can be false, see Counter-example 1
//require.True(t, HasType(err, errorOfInterest))
//require.True(t, HasType(err, errorWithOtherData))
//require.True(t, HasType(err, withPayloadStructError{}))
require.True(t, HasType[withPayloadStructError](err))
var check withPayloadStructError
require.True(t, As(err, &check))
// This can be false, see Counter-example 6
//require.Equal(t, errorOfInterest, check)
}

// HasType implies As for errors with data
if HasType(err, errorOfInterest) {
require.True(t, HasType(err, errorWithOtherData))
require.True(t, HasType(err, withPayloadStructError{}))
if HasType[withPayloadStructError](err) {
// This can be false, see Counter-example 3
//require.True(t, Is(err, errorOfInterest))
var check withPayloadStructError
require.True(t, As(err, &check))
// This can be false, see Counter-example 4
//require.Equal(t, errorOfInterest, check)
}

// As implies a limited form of Is for errors with data
var check withPayloadStructError
if As(err, &check) {
require.True(t, check == errorOfInterest || check == errorWithOtherData)
require.True(t, Is(err, errorOfInterest) || Is(err, errorWithOtherData))
// These can be false, see Counter-example 2
//require.True(t, HasType(err, errorOfInterest))
//require.True(t, HasType(err, errorWithOtherData))
//require.True(t, HasType(err, withPayloadStructError{}))
require.True(t, HasType[withPayloadStructError](err))
}
})
})
Expand All @@ -116,10 +104,9 @@ func TestInvariants(t *testing.T) {
rapid.Just(error(&notTheErrorOfInterest{})),
rapid.Just(error(&payloadLessPtrError{})),
)).Draw(t, "err")
// Is implies As for errors without data
// Is implies HasType and As for errors without data
if Is(err, &payloadLessPtrError{}) {
// This can be false, see Counter-example 1
//require.True(t, HasType(err, &payloadLessPtrError{}))
require.True(t, HasType[*payloadLessPtrError](err))
require.Panics(t, func() {
var check payloadLessPtrError
require.True(t, As(err, &check))
Expand All @@ -128,7 +115,7 @@ func TestInvariants(t *testing.T) {
require.True(t, As(err, &check))
}
// HasType implies Is and As for errors without data
if HasType(err, &payloadLessPtrError{}) {
if HasType[*payloadLessPtrError](err) {
require.True(t, Is(err, &payloadLessPtrError{}))
require.Panics(t, func() {
var check payloadLessPtrError
Expand All @@ -138,11 +125,10 @@ func TestInvariants(t *testing.T) {
require.True(t, As(err, &check))
}
var check *payloadLessPtrError
// As implies Is for errors without data
// As implies Is and HasType for errors without data
if As(err, &check) {
require.True(t, Is(err, &payloadLessPtrError{}))
// This can be false, see Counter-example 2
//require.True(t, errors.HasType(err, &payloadLessPtrError{}))
require.True(t, HasType[*payloadLessPtrError](err))
}
})
})
Expand All @@ -157,15 +143,12 @@ func TestInvariants(t *testing.T) {
rapid.Just(error(errorWithOtherData)),
)).Draw(t, "err")

// Is implies As for errors with data
// Is implies HasType and As for errors with data
if Is(err, errorOfInterest) {
// This is false, see Counter-example 5
//require.False(t, Is(err, errorWithOtherData))
require.False(t, Is(err, &withPayloadPtrError{}))
// These can be false, see Counter-example 1
//require.True(t, HasType(err, errorOfInterest))
//require.True(t, HasType(err, errorWithOtherData))
//require.True(t, HasType(err, withPayloadStructError{}))
require.True(t, HasType[*withPayloadPtrError](err))
require.Panics(t, func() {
var check withPayloadPtrError
_ = As(err, &check)
Expand All @@ -177,9 +160,7 @@ func TestInvariants(t *testing.T) {
}

// HasType implies As for errors with data
if HasType(err, errorOfInterest) {
require.True(t, HasType(err, errorWithOtherData))
require.True(t, HasType(err, &withPayloadPtrError{}))
if HasType[*withPayloadPtrError](err) {
//This can be false, see Counter-example 3
//require.True(t, Is(err, errorOfInterest))
require.Panics(t, func() {
Expand All @@ -191,48 +172,23 @@ func TestInvariants(t *testing.T) {
require.True(t, *check == *errorOfInterest || *check == *errorWithOtherData)
}

// As implies a limited form of Is for errors with data
// As implies HasType and a limited form of Is for errors with data
var check *withPayloadPtrError
if As(err, &check) {
require.True(t, *check == *errorOfInterest || *check == *errorWithOtherData)
require.True(t, Is(err, errorOfInterest) || Is(err, errorWithOtherData))
// These can be false, see Counter-example 2
//require.True(t, HasType(err, errorOfInterest))
//require.True(t, HasType(err, errorWithOtherData))
require.True(t, HasType[*withPayloadPtrError](err))
}
})
})

t.Run("Counter-examples", func(t *testing.T) {
// Counter-example 1. Is does not imply HasType
{
err := Append(payloadLessStructError{}, &notTheErrorOfInterest{})
check := payloadLessStructError{}
require.True(t, Is(err, check))
require.False(t, HasType(err, check))
}
// Counter-example 2. As does not imply HasType
{
err := Append(payloadLessStructError{}, &notTheErrorOfInterest{})
check := payloadLessStructError{}
require.True(t, As(err, &check))
require.False(t, HasType(err, payloadLessStructError{}))
}
// Counter-example 3. HasType does not imply Is
{
err := error(withPayloadStructError{data: 3})
require.True(t, HasType(err, withPayloadStructError{}))
require.True(t, HasType[withPayloadStructError](err))
require.False(t, Is(err, withPayloadStructError{data: 1}))
}
// Counter-example 4. HasType does not imply As
{
err := error(withPayloadStructError{data: 3})
hasTypeCheck := withPayloadStructError{data: 1}
require.True(t, HasType(err, hasTypeCheck))
var valueFromAs withPayloadStructError
require.True(t, As(err, &valueFromAs))
require.NotEqual(t, hasTypeCheck, valueFromAs)
}
// Counter-example 5. Is can return true for distinct values
{
err := Append(withPayloadStructError{data: 3}, withPayloadStructError{data: 1})
Expand Down

0 comments on commit a1c27a7

Please sign in to comment.