github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_decoder_native_slice_test.go (about) 1 package jzon 2 3 import ( 4 "io" 5 "runtime" 6 "runtime/debug" 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestValDecoder_Native_Slice(t *testing.T) { 13 f := func(t *testing.T, data string, ex error, p1, p2 interface{}) { 14 checkDecodeWithStandard(t, DefaultDecoderConfig, data, ex, p1, p2) 15 } 16 t.Run("nil pointer", func(t *testing.T) { 17 f(t, "null", ErrNilPointerReceiver, nil, nil) 18 }) 19 t.Run("eof", func(t *testing.T) { 20 arr1 := []int{1, 2} 21 arr2 := []int{1, 2} 22 f(t, "", io.EOF, &arr1, &arr2) 23 }) 24 t.Run("invalid null", func(t *testing.T) { 25 arr1 := []int{1, 2} 26 arr2 := []int{1, 2} 27 f(t, "nul", io.EOF, &arr1, &arr2) 28 }) 29 t.Run("null", func(t *testing.T) { 30 arr1 := []int{1, 2} 31 arr2 := []int{1, 2} 32 f(t, "null", nil, &arr1, &arr2) 33 }) 34 t.Run("invalid first byte", func(t *testing.T) { 35 arr1 := []int{1, 2} 36 arr2 := []int{1, 2} 37 f(t, `+`, UnexpectedByteError{}, &arr1, &arr2) 38 }) 39 t.Run("eof after bracket", func(t *testing.T) { 40 arr1 := []int{1, 2} 41 arr2 := []int{1, 2} 42 f(t, ` [ `, io.EOF, &arr1, &arr2) 43 }) 44 t.Run("empty", func(t *testing.T) { 45 arr1 := []int{1, 2} 46 arr2 := []int{1, 2} 47 f(t, ` [ ] `, nil, &arr1, &arr2) 48 }) 49 t.Run("bad item", func(t *testing.T) { 50 arr1 := []int{1, 2} 51 arr2 := []int{1, 2} 52 f(t, ` [ + `, InvalidDigitError{}, &arr1, &arr2) 53 }) 54 t.Run("eof after item", func(t *testing.T) { 55 arr1 := []int{1, 2} 56 arr2 := []int{1, 2} 57 f(t, ` [ 3 `, io.EOF, &arr1, &arr2) 58 }) 59 t.Run("lesser item", func(t *testing.T) { 60 arr1 := []int{1, 2} 61 arr2 := []int{1, 2} 62 f(t, ` [ 3 ] `, nil, &arr1, &arr2) 63 }) 64 t.Run("bad item 2", func(t *testing.T) { 65 arr1 := []int{1, 2} 66 arr2 := []int{1, 2} 67 f(t, ` [ "test" ] `, InvalidDigitError{}, &arr1, &arr2) 68 }) 69 t.Run("invalid comma", func(t *testing.T) { 70 arr1 := []int{1, 2} 71 arr2 := []int{1, 2} 72 f(t, ` [ 3 [ `, UnexpectedByteError{}, &arr1, &arr2) 73 }) 74 t.Run("more item", func(t *testing.T) { 75 arr1 := []int{1, 2} 76 arr2 := []int{1, 2} 77 f(t, ` [ 3 , 4 , 5 ] `, nil, &arr1, &arr2) 78 }) 79 t.Run("more item error", func(t *testing.T) { 80 arr1 := []int{1, 2} 81 arr2 := []int{1, 2} 82 f(t, ` [ 3 , 4 , "test" ] `, InvalidDigitError{}, &arr1, &arr2) 83 }) 84 debug.FreeOSMemory() 85 } 86 87 func TestValDecoder_Native_Slice_Memory(t *testing.T) { 88 t.Run("test1", func(t *testing.T) { 89 f := func(i int) []*int { 90 pi := &i 91 runtime.SetFinalizer(pi, func(_ *int) { 92 t.Logf("finalizing") 93 }) 94 return []*int{pi} 95 } 96 arr := f(1) 97 err := Unmarshal([]byte(`[]`), &arr) 98 require.NoError(t, err) 99 debug.FreeOSMemory() 100 t.Logf("please check if the memory has been freed") 101 }) 102 t.Run("test2", func(t *testing.T) { 103 type st struct { 104 p *int 105 } 106 f := func(i int) []*st { 107 pi := &i 108 runtime.SetFinalizer(pi, func(_ *int) { 109 t.Logf("finalizing") 110 }) 111 return []*st{{p: pi}} 112 } 113 arr := f(1) 114 err := Unmarshal([]byte(`[]`), &arr) 115 require.NoError(t, err) 116 debug.FreeOSMemory() 117 t.Logf("please check if the memory has been freed") 118 }) 119 } 120 121 func TestValDecoder_Native_Slice_AllocateError(t *testing.T) { 122 type bigSt struct { 123 A string 124 B string 125 C string 126 D string 127 E string 128 } 129 var arr []bigSt 130 err := Unmarshal([]byte(`[{ 131 "E": "test0" 132 }, { 133 "E": "test1" 134 }]`), &arr) 135 require.NoError(t, err) 136 require.Len(t, arr, 2) 137 require.Equal(t, "test0", arr[0].E) 138 require.Equal(t, "test1", arr[1].E) 139 }