github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/decoder/stream_test.go (about) 1 /* 2 * Copyright 2021 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package decoder 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "io" 23 "io/ioutil" 24 "strings" 25 "testing" 26 27 "github.com/goshafaq/sonic/option" 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 var ( 33 DefaultBufferSize = option.DefaultDecoderBufferSize 34 _Single_JSON = `{"aaaaa":"` + strings.Repeat("b", int(DefaultBufferSize)) + `"} { ` 35 _Double_JSON = `{"aaaaa":"` + strings.Repeat("b", int(DefaultBufferSize)) + `"} {"11111":"` + strings.Repeat("2", int(DefaultBufferSize)) + `"}` 36 _Triple_JSON = `{"aaaaa":"` + strings.Repeat("b", int(DefaultBufferSize)) + `"}{ } {"11111":"` + 37 strings.Repeat("2", int(DefaultBufferSize)) + `"} b {}` 38 ) 39 40 func TestStreamError(t *testing.T) { 41 var qs = []string{ 42 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"`, 43 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"}`, 44 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `""}`, 45 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":}`, 46 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":]`, 47 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":1x`, 48 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":1x}`, 49 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":1x]`, 50 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":t`, 51 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":t}`, 52 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":true]`, 53 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":f`, 54 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":f}`, 55 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":false]`, 56 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":n`, 57 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":n}`, 58 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":null]`, 59 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":"`, 60 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":"a`, 61 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":"a}`, 62 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":"a"`, 63 `{` + strings.Repeat(" ", int(DefaultBufferSize)) + `"":"a"]`, 64 } 65 66 for i, q := range qs { 67 var qq = []byte(q[:int(DefaultBufferSize)] + strings.Repeat(" ", i*100) + q[int(DefaultBufferSize):]) 68 var obj interface{} 69 require.NotNil(t, NewStreamDecoder(bytes.NewReader(qq)).Decode(&obj)) 70 } 71 } 72 73 func TestDecodeEmpty(t *testing.T) { 74 var str = `` 75 var r1 = strings.NewReader(str) 76 var v1 interface{} 77 var d1 = json.NewDecoder(r1) 78 var r2 = strings.NewReader(str) 79 var v2 interface{} 80 var d2 = NewStreamDecoder(r2) 81 es1 := d1.Decode(&v1) 82 ee1 := d2.Decode(&v2) 83 assert.Equal(t, es1, ee1) 84 assert.Equal(t, v1, v2) 85 } 86 87 type HaltReader struct { 88 halts map[int]bool 89 buf string 90 p int 91 } 92 93 func NewHaltReader(buf string, halts map[int]bool) *HaltReader { 94 return &HaltReader{ 95 halts: halts, 96 buf: buf, 97 p: 0, 98 } 99 } 100 101 func (self *HaltReader) Read(p []byte) (int, error) { 102 t := 0 103 for t < len(p) { 104 if self.p >= len(self.buf) { 105 return t, io.EOF 106 } 107 if b, ok := self.halts[self.p]; b { 108 self.halts[self.p] = false 109 return t, nil 110 } else if ok { 111 delete(self.halts, self.p) 112 return 0, nil 113 } 114 p[t] = self.buf[self.p] 115 self.p++ 116 t++ 117 } 118 return t, nil 119 } 120 121 func (self *HaltReader) Reset(buf string) { 122 self.p = 0 123 self.buf = buf 124 } 125 126 var testHalts = func() map[int]bool { 127 return map[int]bool{ 128 1: true, 129 10: true, 130 20: true} 131 } 132 133 func TestBuffered(t *testing.T) { 134 var str = _Triple_JSON 135 var r1 = NewHaltReader(str, testHalts()) 136 var v1 map[string]interface{} 137 var d1 = json.NewDecoder(r1) 138 require.Nil(t, d1.Decode(&v1)) 139 var r2 = NewHaltReader(str, testHalts()) 140 var v2 map[string]interface{} 141 var d2 = NewStreamDecoder(r2) 142 require.Nil(t, d2.Decode(&v2)) 143 left1, err1 := ioutil.ReadAll(d1.Buffered()) 144 require.Nil(t, err1) 145 left2, err2 := ioutil.ReadAll(d2.Buffered()) 146 require.Nil(t, err2) 147 require.Equal(t, d1.InputOffset(), d2.InputOffset()) 148 min := len(left1) 149 if min > len(left2) { 150 min = len(left2) 151 } 152 require.Equal(t, left1[:min], left2[:min]) 153 154 es4 := d1.Decode(&v1) 155 ee4 := d2.Decode(&v2) 156 assert.Equal(t, es4, ee4) 157 assert.Equal(t, d1.InputOffset(), d2.InputOffset()) 158 159 es2 := d1.Decode(&v1) 160 ee2 := d2.Decode(&v2) 161 assert.Equal(t, es2, ee2) 162 assert.Equal(t, d1.InputOffset(), d2.InputOffset()) 163 } 164 165 func BenchmarkDecodeStream_Std(b *testing.B) { 166 b.Run("single", func(b *testing.B) { 167 var str = _Single_JSON 168 for i := 0; i < b.N; i++ { 169 var r1 = strings.NewReader(str) 170 var v1 map[string]interface{} 171 dc := json.NewDecoder(r1) 172 _ = dc.Decode(&v1) 173 _ = dc.Decode(&v1) 174 } 175 }) 176 177 b.Run("double", func(b *testing.B) { 178 var str = _Double_JSON 179 for i := 0; i < b.N; i++ { 180 var r1 = strings.NewReader(str) 181 var v1 map[string]interface{} 182 dc := json.NewDecoder(r1) 183 _ = dc.Decode(&v1) 184 _ = dc.Decode(&v1) 185 } 186 }) 187 188 b.Run("halt", func(b *testing.B) { 189 var str = _Double_JSON 190 for i := 0; i < b.N; i++ { 191 var r1 = NewHaltReader(str, testHalts()) 192 var v1 map[string]interface{} 193 dc := json.NewDecoder(r1) 194 _ = dc.Decode(&v1) 195 } 196 }) 197 } 198 199 // func BenchmarkDecodeError_Sonic(b *testing.B) { 200 // var str = `\b测试1234` 201 // for i:=0; i<b.N; i++ { 202 // var v1 map[string]interface{} 203 // _ = NewDecoder(str).Decode(&v1) 204 // } 205 // } 206 207 func BenchmarkDecodeStream_Sonic(b *testing.B) { 208 b.Run("single", func(b *testing.B) { 209 var str = _Single_JSON 210 for i := 0; i < b.N; i++ { 211 var r1 = strings.NewReader(str) 212 var v1 map[string]interface{} 213 dc := NewStreamDecoder(r1) 214 _ = dc.Decode(&v1) 215 _ = dc.Decode(&v1) 216 } 217 }) 218 219 b.Run("double", func(b *testing.B) { 220 var str = _Double_JSON 221 for i := 0; i < b.N; i++ { 222 var r1 = strings.NewReader(str) 223 var v1 map[string]interface{} 224 dc := NewStreamDecoder(r1) 225 _ = dc.Decode(&v1) 226 _ = dc.Decode(&v1) 227 } 228 }) 229 230 b.Run("halt", func(b *testing.B) { 231 var str = _Double_JSON 232 for i := 0; i < b.N; i++ { 233 var r1 = NewHaltReader(str, testHalts()) 234 var v1 map[string]interface{} 235 dc := NewStreamDecoder(r1) 236 _ = dc.Decode(&v1) 237 } 238 }) 239 }