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  }