github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/infra/errcode/code_test.go (about) 1 package errcode 2 3 import ( 4 "errors" 5 "fmt" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestCode(t *testing.T) { 13 reg := New() 14 dummy1 := reg.Register(100001, "") 15 dummy2 := reg.RegisterReserved(100002, "dummy2") 16 17 assert.Equal(t, dummy1.Error(), "[100001] unknown") 18 assert.Equal(t, dummy2.Error(), "[100002] dummy2") 19 20 got1 := func() error { return dummy1 }() 21 got2 := func() error { return dummy2 }() 22 assert.True(t, Is(got1, dummy1)) 23 assert.True(t, Is(got2, dummy2)) 24 assert.True(t, IsErrCode(got1)) 25 assert.True(t, IsErrCode(got2)) 26 27 assert.False(t, Is(nil, dummy1)) 28 assert.False(t, Is(errors.New("dummy1"), dummy1)) 29 assert.False(t, IsErrCode(nil)) 30 assert.False(t, IsErrCode(errors.New("dummy1"))) 31 32 json1, _ := dummy1.MarshalJSON() 33 json2, _ := dummy2.MarshalJSON() 34 assert.Equal(t, []byte(`{"code":100001}`), json1) 35 assert.Equal(t, []byte(`{"code":100002,"message":"dummy2"}`), json2) 36 } 37 38 func TestCodeFormat(t *testing.T) { 39 reg := New() 40 badReqErr := reg.Register(100400, "bad request") 41 42 t.Run("no details", func(t *testing.T) { 43 err := func() error { 44 return badReqErr 45 }() 46 47 got1 := fmt.Sprintf("%v", err) 48 assert.Equal(t, "[100400] bad request", got1) 49 50 got2 := fmt.Sprintf("%+v", err) 51 assert.Equal(t, "[100400] bad request", got2) 52 }) 53 54 t.Run("with details", func(t *testing.T) { 55 err := func() error { 56 return badReqErr.AddDetails("test detail", 12345) 57 }() 58 59 got1 := fmt.Sprintf("%v", err) 60 assert.Equal(t, "[100400] bad request", got1) 61 62 got2 := fmt.Sprintf("%+v", err) 63 t.Log(got2) 64 assert.Equal(t, "[100400] bad request\ndetails:\n - test detail\n - 12345", got2) 65 }) 66 } 67 68 func TestDetails(t *testing.T) { 69 reg := New() 70 testErr := reg.Register(1001, "test error") 71 72 t.Run("not ErrCode", func(t *testing.T) { 73 err := errors.New("not an ErrCode") 74 got := Details(err) 75 assert.Nil(t, got) 76 }) 77 78 t.Run("no details", func(t *testing.T) { 79 err := testErr 80 got := Details(err) 81 assert.Nil(t, got) 82 }) 83 84 t.Run("with details", func(t *testing.T) { 85 err := testErr.AddDetails("test detail", 12345) 86 got := Details(err) 87 require.Len(t, got, 2) 88 assert.Equal(t, "test detail", got[0]) 89 assert.Equal(t, 12345, got[1]) 90 }) 91 92 t.Run("wrapped", func(t *testing.T) { 93 err := func() error { 94 err1 := testErr.AddDetails("test detail", 12345) 95 return fmt.Errorf("wrap message: %w", err1) 96 }() 97 got := Details(err) 98 require.Len(t, got, 2) 99 assert.Equal(t, "test detail", got[0]) 100 assert.Equal(t, 12345, got[1]) 101 }) 102 } 103 104 func TestIs(t *testing.T) { 105 reg := New() 106 code1 := reg.Register(100001, "test code1") 107 108 detailsErr := code1.AddDetails("dummy detail") 109 assert.True(t, Is(detailsErr, code1)) 110 111 wrapErr1 := &testErrWrapper1{error: detailsErr} 112 assert.True(t, Is(detailsErr, code1)) 113 114 wrapErr2 := &testErrWrapper2{error: detailsErr} 115 assert.True(t, Is(wrapErr2, code1)) 116 117 wrapErr3 := &testErrWrapper2{error: wrapErr1} 118 assert.True(t, Is(wrapErr3, code1)) 119 120 wrapErr4 := &testErrWrapper1{error: wrapErr2} 121 assert.True(t, Is(wrapErr4, code1)) 122 } 123 124 func TestErrorsCompatibility(t *testing.T) { 125 reg := New() 126 code1 := reg.Register(100001, "test code1") 127 128 detailsErr := code1.AddDetails("dummy detail") 129 assert.True(t, errors.Is(detailsErr, code1)) 130 131 wrapErr1 := &testErrWrapper2{error: detailsErr} 132 assert.True(t, errors.Is(wrapErr1, code1)) 133 134 wrapErr2 := &testErrWrapper2{error: wrapErr1} 135 assert.True(t, errors.Is(wrapErr2, code1)) 136 } 137 138 type testErrWrapper1 struct { 139 error 140 extra any 141 } 142 143 func (e *testErrWrapper1) Cause() error { 144 return e.error 145 } 146 147 type testErrWrapper2 struct { 148 error 149 extra any 150 } 151 152 func (e *testErrWrapper2) Unwrap() error { 153 return e.error 154 }