github.com/pachyderm/pachyderm@v1.13.4/src/client/pkg/errors/testing/errors_test.go (about) 1 package testing 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/pachyderm/pachyderm/src/client/pkg/errors" 8 "github.com/pachyderm/pachyderm/src/client/pkg/require" 9 ) 10 11 // FooErr is an error with a normal receiver for fulfilling the error interface 12 type FooErr struct { 13 val int 14 } 15 16 func (err FooErr) Error() string { 17 return fmt.Sprintf("foo-%d", err.val) 18 } 19 20 // PtrFooErr is an error with a pointer receiver for fulfilling the error interface 21 type PtrFooErr struct { 22 val int 23 } 24 25 func (err *PtrFooErr) Error() string { 26 return fmt.Sprintf("fooptr-%d", err.val) 27 } 28 29 // IntErr is an interface that also fulfills the error interface 30 type IntErr interface { 31 Int() int 32 Error() string 33 } 34 35 // ConcreteIntErr is an implementation of the IntErr interface using a normal receiver 36 type ConcreteIntErr struct { 37 val int 38 } 39 40 func (err ConcreteIntErr) Int() int { 41 return err.val 42 } 43 44 func (err ConcreteIntErr) Error() string { 45 return fmt.Sprintf("int-%d", err.Int()) 46 } 47 48 // ConcreteIntErr is an implementation of the IntErr interface using a pointer receiver 49 type ConcretePtrIntErr struct { 50 val int 51 } 52 53 func (err *ConcretePtrIntErr) Int() int { 54 return err.val 55 } 56 57 func (err *ConcretePtrIntErr) Error() string { 58 return fmt.Sprintf("intptr-%d", err.Int()) 59 } 60 61 // OtherErr is a different error type to be used for failed casting 62 type OtherErr struct{} 63 64 func (err OtherErr) Error() string { 65 return "other" 66 } 67 68 func TestAsFooErr(t *testing.T) { 69 var err error 70 fooerr := &FooErr{} 71 otherErr := &OtherErr{} 72 73 err = FooErr{1} 74 require.True(t, errors.As(err, &FooErr{})) 75 require.False(t, errors.As(err, &OtherErr{})) 76 77 err = FooErr{2} 78 require.True(t, errors.As(err, fooerr)) 79 require.False(t, errors.As(err, otherErr)) 80 require.Equal(t, fooerr, &FooErr{2}) 81 82 err = FooErr{3} 83 require.True(t, errors.As(err, &fooerr)) 84 require.False(t, errors.As(err, &otherErr)) 85 require.Equal(t, fooerr, &FooErr{3}) 86 87 err = &FooErr{4} 88 require.True(t, errors.As(err, &FooErr{})) 89 require.False(t, errors.As(err, &OtherErr{})) 90 91 err = &FooErr{5} 92 require.True(t, errors.As(err, fooerr)) 93 require.False(t, errors.As(err, otherErr)) 94 require.Equal(t, fooerr, &FooErr{5}) 95 96 err = &FooErr{6} 97 require.True(t, errors.As(err, &fooerr)) 98 require.False(t, errors.As(err, &otherErr)) 99 require.Equal(t, fooerr, &FooErr{6}) 100 } 101 102 func TestAsPtrFooErr(t *testing.T) { 103 var err error 104 fooptrerr := &PtrFooErr{} 105 otherErr := &OtherErr{} 106 107 // these don't compile - fooptrerr can't be used as an error unless it's a pointer 108 // err = PtrFooErr{1} 109 // require.True(t, errors.As(err, &PtrFooErr{})) 110 // require.False(t, errors.As(err, &OtherErr{})) 111 112 // err = PtrFooErr{2} 113 // require.True(t, errors.As(err, fooptrerr)) 114 // require.False(t, errors.As(err, otherErr)) 115 // require.Equal(t, fooptrerr, &PtrFooErr{2}) 116 117 // err = PtrFooErr{3} 118 // require.True(t, errors.As(err, &fooptrerr)) 119 // require.False(t, errors.As(err, &otherErr)) 120 // require.Equal(t, fooptrerr, &PtrFooErr{3}) 121 122 err = &PtrFooErr{4} 123 require.True(t, errors.As(err, &PtrFooErr{})) 124 require.False(t, errors.As(err, &OtherErr{})) 125 126 err = &PtrFooErr{5} 127 require.True(t, errors.As(err, fooptrerr)) 128 require.False(t, errors.As(err, otherErr)) 129 require.Equal(t, fooptrerr, &PtrFooErr{5}) 130 131 err = &PtrFooErr{6} 132 require.True(t, errors.As(err, &fooptrerr)) 133 require.False(t, errors.As(err, &otherErr)) 134 require.Equal(t, fooptrerr, &PtrFooErr{6}) 135 } 136 137 func TestAsConcreteIntErr(t *testing.T) { 138 var err error 139 var interrFace IntErr 140 var interr IntErr = &ConcreteIntErr{} 141 otherErr := &OtherErr{} 142 143 err = ConcreteIntErr{1} 144 // this doesn't compile - can't construct an IntErr{} as it's an interface 145 // require.True(t, errors.As(err, &IntErr{})) 146 require.False(t, errors.As(err, &OtherErr{})) 147 148 err = ConcreteIntErr{2} 149 require.True(t, errors.As(err, interr)) 150 require.False(t, errors.As(err, otherErr)) 151 require.Equal(t, &ConcreteIntErr{2}, interr) 152 153 err = ConcreteIntErr{3} 154 require.True(t, errors.As(err, &interr)) 155 require.True(t, errors.As(err, &interrFace)) 156 require.False(t, errors.As(err, &otherErr)) 157 require.Equal(t, ConcreteIntErr{3}, interr) 158 require.Equal(t, ConcreteIntErr{3}, interrFace) 159 160 err = &ConcreteIntErr{4} 161 // this doesn't compile - can't construct an IntErr{} as it's an interface 162 // require.True(t, errors.As(err, &IntErr{})) 163 require.False(t, errors.As(err, &OtherErr{})) 164 165 err = &ConcreteIntErr{5} 166 interr = &ConcreteIntErr{} 167 require.True(t, errors.As(err, interr)) 168 require.False(t, errors.As(err, otherErr)) 169 require.Equal(t, &ConcreteIntErr{5}, interr) 170 171 interrFace = nil 172 err = &ConcreteIntErr{6} 173 require.True(t, errors.As(err, &interr)) 174 require.True(t, errors.As(err, &interrFace)) 175 require.False(t, errors.As(err, &otherErr)) 176 require.Equal(t, &ConcreteIntErr{6}, interr) 177 require.Equal(t, &ConcreteIntErr{6}, interrFace) 178 } 179 180 func TestAsConcretePtrIntErr(t *testing.T) { 181 var err error 182 var interrFace IntErr 183 var interr IntErr = &ConcretePtrIntErr{} 184 otherErr := &OtherErr{} 185 186 // these don't compile - ConcretePtrIntErr can't be used as an error unless it's a pointer 187 // err = ConcretePtrIntErr{1} 188 // require.True(t, errors.As(err, &IntErr{})) 189 // require.False(t, errors.As(err, &OtherErr{})) 190 191 // err = ConcretePtrIntErr{2} 192 // require.True(t, errors.As(err, interr)) 193 // require.False(t, errors.As(err, otherErr)) 194 // require.Equal(t, &ConcretePtrIntErr{2}, interr) 195 196 // err = ConcretePtrIntErr{3} 197 // require.True(t, errors.As(err, &interr)) 198 // require.False(t, errors.As(err, &otherErr)) 199 // require.Equal(t, &ConcretePtrIntErr{3}, interr) 200 201 err = &ConcretePtrIntErr{4} 202 // this doesn't compile - can't construct an IntErr{} as it's an interface 203 // require.True(t, errors.As(err, &IntErr{})) 204 require.False(t, errors.As(err, &OtherErr{})) 205 206 err = &ConcretePtrIntErr{5} 207 require.True(t, errors.As(err, interr)) 208 require.False(t, errors.As(err, otherErr)) 209 require.Equal(t, &ConcretePtrIntErr{5}, interr) 210 211 interrFace = nil 212 err = &ConcretePtrIntErr{6} 213 require.True(t, errors.As(err, &interr)) 214 require.True(t, errors.As(err, &interrFace)) 215 require.False(t, errors.As(err, &otherErr)) 216 require.Equal(t, &ConcretePtrIntErr{6}, interr) 217 require.Equal(t, &ConcretePtrIntErr{6}, interrFace) 218 }