Skip to content

Commit 553e5d7

Browse files
committed
tests for errors.As
1 parent 9e108ae commit 553e5d7

2 files changed

Lines changed: 55 additions & 2 deletions

File tree

error_113.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
package errorx
44

5+
import "reflect"
6+
57
// todo godoc
8+
// NB: Call to errors.As() converts any type of errorx error to any other type, therefore such calls may break semantics.
9+
// Note than calls to errors.Is() do not suffer from the same issue.
10+
// todo add errorx.As() ?
11+
// todo make another type for passing into errors.As()?
12+
// todo when fixed, add tests for wrap/decorate etc.
613
func (e *Error) As(target interface{}) bool {
714
targetError, ok := target.(*error)
815
if !ok {
@@ -13,7 +20,8 @@ func (e *Error) As(target interface{}) bool {
1320
return false
1421
}
1522

16-
// todo inject
23+
targetVal := reflect.ValueOf(target)
24+
targetVal.Elem().Set(reflect.ValueOf(e))
1725
return true
1826
}
1927

@@ -24,7 +32,7 @@ func (e *Error) Is(target error) bool {
2432
return false
2533
}
2634

27-
return e.IsOfType(typedTarget.Type()) // todo test with parents
35+
return e.IsOfType(typedTarget.Type())
2836
}
2937

3038
// todo godoc

error_113_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package errorx
44

55
import (
66
"errors"
7+
"fmt"
78
"io"
89
"testing"
910

@@ -100,4 +101,48 @@ func TestErrorIs(t *testing.T) {
100101
err := Decorate(io.EOF,"")
101102
require.True(t, errors.Is(err, io.EOF))
102103
})
104+
}
105+
106+
func TestErrorAs(t *testing.T) {
107+
t.Run("Trivial", func(t *testing.T) {
108+
err := fooReturnsError()
109+
target := testType.NewWithNoMessage()
110+
require.True(t, errors.As(err, &target))
111+
require.EqualValues(t, "whoops", target.Message())
112+
output := fmt.Sprintf("%+v", target)
113+
require.Contains(t, output, "fooReturnsError", output)
114+
})
115+
116+
// Current errors.As allows no customization in this behaviour; if go types are assignable, here we go
117+
t.Run("NegativeBroken", func(t *testing.T) {
118+
err := fooReturnsError()
119+
target := testTypeBar1.NewWithNoMessage()
120+
require.True(t, errors.As(err, &target))
121+
require.EqualValues(t, "whoops", target.Message())
122+
require.True(t, IsOfType(target, testType))
123+
require.False(t, IsOfType(target, testTypeBar1))
124+
})
125+
126+
t.Run("Negative", func(t *testing.T) {
127+
err := io.EOF
128+
target := testTypeBar1.NewWithNoMessage()
129+
require.False(t, errors.As(err, &target))
130+
})
131+
132+
t.Run("DecorateForeign", func(t *testing.T) {
133+
err := Decorate(myErr("test"),"")
134+
var target myErr
135+
require.True(t, errors.As(err, &target))
136+
require.EqualValues(t, "test", target.Error())
137+
})
138+
}
139+
140+
func fooReturnsError() error {
141+
return testType.New("whoops")
142+
}
143+
144+
type myErr string
145+
146+
func (e myErr) Error() string {
147+
return string(e)
103148
}

0 commit comments

Comments
 (0)