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  }