github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/decoder_test.go (about) 1 package jzon 2 3 import ( 4 "encoding/json" 5 "io" 6 "io/ioutil" 7 "strings" 8 "testing" 9 "testing/iotest" 10 11 "github.com/stretchr/testify/require" 12 ) 13 14 type decFace interface { 15 UseNumber() 16 17 DisallowUnknownFields() 18 19 Decode(interface{}) error 20 21 Buffered() io.Reader 22 23 // This is incompatible 24 // Token() (json.Token, error) 25 26 More() bool 27 } 28 29 type inputOffset interface { 30 // Not available for go<1.13 31 InputOffset() int64 32 } 33 34 var _ decFace = &json.Decoder{} 35 var _ decFace = &Decoder{} 36 37 func TestDecoder(t *testing.T) { 38 t.Run("consecutive", func(t *testing.T) { 39 t.Run("success", func(t *testing.T) { 40 must := require.New(t) 41 42 newReader := func() io.Reader { 43 s := ` {} {} ` 44 return iotest.OneByteReader(strings.NewReader(s)) 45 } 46 47 check := func(dec decFace, length int, expMore bool, leftOffset, rightOffset int64) { 48 buffered := dec.Buffered() 49 if buffered == nil { 50 return 51 } 52 b, err := ioutil.ReadAll(buffered) 53 must.NoError(err) 54 if length > 0 { 55 t.Logf("%T: %q", dec, b) 56 } 57 must.True(length >= len(b)) 58 59 ofI, ofIok := dec.(inputOffset) 60 if ofIok { 61 offset := ofI.InputOffset() 62 // t.Logf("%T %d", dec, offset) 63 must.True(leftOffset <= offset, "%T %d > %d", dec, leftOffset, offset) 64 must.True(rightOffset >= offset, "%T %d < %d", dec, rightOffset, offset) 65 } 66 67 more := dec.More() 68 must.Equal(expMore, more, "%T", dec) 69 70 if ofIok { 71 offset := ofI.InputOffset() 72 // t.Logf("%T %d", dec, offset) 73 must.True(leftOffset <= offset, "%T %d > %d", dec, leftOffset, offset) 74 must.True(rightOffset >= offset, "%T %d < %d", dec, rightOffset, offset) 75 } 76 } 77 78 f := func(dec decFace) { 79 var i, i2, i3 interface{} 80 81 check(dec, 0, true, 0, 1) 82 83 err := dec.Decode(&i) 84 must.NoError(err, "%T", dec) 85 check(dec, 0, true, 3, 4) 86 87 err2 := dec.Decode(&i2) 88 must.NoError(err2, "%T", dec) 89 check(dec, 0, false, 6, 7) 90 91 err3 := dec.Decode(&i3) 92 must.Equal(io.EOF, err3, "%T", dec) 93 check(dec, 1, false, 6, 7) 94 } 95 f(json.NewDecoder(newReader())) 96 dec := NewDecoder(newReader()) 97 defer dec.Release() 98 f(dec) 99 }) 100 t.Run("failure at start", func(t *testing.T) { 101 must := require.New(t) 102 103 newReader := func() io.Reader { 104 s := ` } {} ` 105 return iotest.OneByteReader(strings.NewReader(s)) 106 } 107 f := func(dec decFace) { 108 var i, i2 interface{} 109 110 err := dec.Decode(&i) 111 t.Logf("%T %v", dec, err) 112 must.Error(err) 113 114 err2 := dec.Decode(&i2) 115 t.Logf("%T %v", dec, err2) 116 must.Equal(err2, err) 117 } 118 f(json.NewDecoder(newReader())) 119 dec := NewDecoder(newReader()) 120 defer dec.Release() 121 f(dec) 122 }) 123 t.Run("failure at middle", func(t *testing.T) { 124 must := require.New(t) 125 126 newReader := func() io.Reader { 127 s := ` {} } ` 128 return iotest.OneByteReader(strings.NewReader(s)) 129 } 130 f := func(dec decFace) { 131 var i, i2 interface{} 132 133 err := dec.Decode(&i) 134 must.NoError(err) 135 136 err2 := dec.Decode(&i2) 137 t.Logf("%T %v", dec, err2) 138 must.Error(err2) 139 } 140 f(json.NewDecoder(newReader())) 141 dec := NewDecoder(newReader()) 142 defer dec.Release() 143 f(dec) 144 }) 145 }) 146 } 147 148 func TestDecoder_UseNumber(t *testing.T) { 149 must := require.New(t) 150 s := "123.456" 151 newReader := func() io.Reader { 152 return strings.NewReader(s) 153 } 154 f := func(dec decFace) { 155 dec.UseNumber() 156 var i interface{} 157 err := dec.Decode(&i) 158 must.NoError(err) 159 must.Equal(json.Number(s), i) 160 } 161 f(json.NewDecoder(newReader())) 162 dec := NewDecoder(newReader()) 163 defer dec.Release() 164 f(dec) 165 } 166 167 func TestDecoder_DisallowUnknownFields(t *testing.T) { 168 must := require.New(t) 169 s := `{"k":"v"}` 170 newReader := func() io.Reader { 171 return strings.NewReader(s) 172 } 173 f := func(dec decFace) { 174 dec.DisallowUnknownFields() 175 var i struct{} 176 err := dec.Decode(&i) 177 t.Log(err) 178 must.Error(err) 179 } 180 f(json.NewDecoder(newReader())) 181 dec := NewDecoder(newReader()) 182 defer dec.Release() 183 f(dec) 184 }