codeberg.org/gruf/go-errors/v2@v2.3.1/standard_test.go (about) 1 package errors_test 2 3 import ( 4 "crypto/x509" 5 "fmt" 6 "io/fs" 7 "os" 8 "testing" 9 10 "codeberg.org/gruf/go-errors/v2" 11 ) 12 13 func TestAs(t *testing.T) { 14 var errT errorT 15 var errP *fs.PathError 16 var p *poser 17 _, errF := os.Open("non-existing") 18 poserErr := &poser{"oh no", nil} 19 testCases := []struct { 20 err error 21 target error 22 check func(err, target error) bool 23 match bool 24 }{{ 25 nil, 26 errP, 27 func(err, target error) bool { 28 check := errors.AsV2[*fs.PathError](err) 29 return check != nil 30 }, 31 false, 32 }, { 33 wrapped{"pitied the fool", errorT{"T"}}, 34 errT, 35 func(err, target error) bool { 36 check := errors.AsV2[errorT](err) 37 return check != errorT{} 38 }, 39 true, 40 }, { 41 errF, 42 errP, 43 func(err, target error) bool { 44 check := errors.AsV2[*fs.PathError](err) 45 return check != nil 46 }, 47 true, 48 }, { 49 errorT{}, 50 errP, 51 func(err, target error) bool { 52 check := errors.AsV2[*fs.PathError](err) 53 return check != nil 54 }, 55 false, 56 }, { 57 wrapped{"wrapped", nil}, 58 &errT, 59 func(err, target error) bool { 60 check := errors.AsV2[*errorT](err) 61 return check != nil 62 }, 63 false, 64 }, { 65 &poser{"error", nil}, 66 &errT, 67 func(err, target error) bool { 68 check := errors.AsV2[errorT](err) 69 return check != errorT{} 70 }, 71 true, 72 }, { 73 poserErr, 74 p, 75 func(err, target error) bool { 76 check := errors.AsV2[*poser](err) 77 return check != nil 78 }, 79 true, 80 }, { 81 fmt.Errorf("text: %w", &x509.UnknownAuthorityError{}), 82 (*x509.UnknownAuthorityError)(nil), 83 func(err, target error) bool { 84 check := errors.AsV2[*x509.UnknownAuthorityError](err) 85 return check != nil 86 }, 87 true, 88 }, { 89 fmt.Errorf("text: %w", &x509.CertificateInvalidError{}), 90 (*x509.UnknownAuthorityError)(nil), 91 func(err, target error) bool { 92 check := errors.AsV2[*x509.UnknownAuthorityError](err) 93 return check != nil 94 }, 95 false, 96 }} 97 for i, tc := range testCases { 98 name := fmt.Sprintf("%d:(As(Errorf(..., %v)) == %#v)", i, tc.err, tc.target) 99 // Clear the target pointer, in case it was set in a previous test. 100 t.Run(name, func(t *testing.T) { 101 if tc.check(tc.err, tc.target) != tc.match { 102 t.Fail() 103 } 104 }) 105 } 106 } 107 108 type poser struct { 109 msg string 110 111 f func(error) bool 112 } 113 114 var poserPathErr = &fs.PathError{Op: "poser"} 115 116 func (p *poser) Error() string { return p.msg } 117 118 func (p *poser) Is(err error) bool { return p.f != nil && p.f(err) } 119 120 func (p *poser) As(err interface{}) bool { 121 switch x := err.(type) { 122 case **poser: 123 *x = p 124 125 case *errorT: 126 *x = errorT{"poser"} 127 128 case **fs.PathError: 129 *x = poserPathErr 130 131 default: 132 return false 133 } 134 135 return true 136 } 137 138 type errorT struct{ s string } 139 140 func (e errorT) Error() string { return fmt.Sprintf("errorT(%s)", e.s) } 141 142 type wrapped struct { 143 msg string 144 145 err error 146 } 147 148 func (e wrapped) Error() string { return e.msg } 149 150 func (e wrapped) Unwrap() error { return e.err } 151 152 type errorUncomparable struct { 153 f []string 154 } 155 156 func (errorUncomparable) Error() string { 157 return "uncomparable error" 158 } 159 160 func (errorUncomparable) Is(target error) bool { 161 _, ok := target.(errorUncomparable) 162 163 return ok 164 }