github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/decoder/decoder_amd64_test.go (about) 1 //go:build amd64 && go1.16 && !go1.22 2 // +build amd64,go1.16,!go1.22 3 4 /* 5 * Copyright 2021 ByteDance Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package decoder 21 22 import ( 23 "encoding/json" 24 "reflect" 25 "strings" 26 "testing" 27 28 "github.com/goshafaq/sonic/internal/rt" 29 "github.com/stretchr/testify/assert" 30 ) 31 32 func TestSkipMismatchTypeAmd64Error(t *testing.T) { 33 t.Run("struct", func(t *testing.T) { 34 println("TestSkipError") 35 type skiptype struct { 36 A int `json:"a"` 37 B string `json:"b"` 38 39 Pass *int `json:"pass"` 40 41 C struct { 42 Pass4 interface{} `json:"pass4"` 43 44 D struct { 45 E float32 `json:"e"` 46 } `json:"d"` 47 48 Pass2 int `json:"pass2"` 49 } `json:"c"` 50 51 E bool `json:"e"` 52 F []int `json:"f"` 53 G map[string]int `json:"g"` 54 H bool `json:"h,string"` 55 56 Pass3 int `json:"pass2"` 57 58 I json.Number `json:"i"` 59 } 60 var obj, obj2 = &skiptype{Pass: new(int)}, &skiptype{Pass: new(int)} 61 var data = `{"a":"","b":1,"c":{"d":true,"pass2":1,"pass4":true},"e":{},"f":"","g":[],"pass":null,"h":"1.0","i":true,"pass3":1}` 62 d := NewDecoder(data) 63 err := d.Decode(obj) 64 err2 := json.Unmarshal([]byte(data), obj2) 65 println(err2.Error()) 66 assert.Equal(t, err2 == nil, err == nil) 67 // assert.Equal(t, len(data), d.i) 68 assert.Equal(t, obj2, obj) 69 if te, ok := err.(*MismatchTypeError); ok { 70 assert.Equal(t, reflect.TypeOf(obj.I), te.Type) 71 assert.Equal(t, strings.Index(data, `"i":t`)+4, te.Pos) 72 println(err.Error()) 73 } else { 74 t.Fatal("invalid error") 75 } 76 }) 77 t.Run("short array", func(t *testing.T) { 78 var obj, obj2 = &[]int{}, &[]int{} 79 var data = `[""]` 80 d := NewDecoder(data) 81 err := d.Decode(obj) 82 err2 := json.Unmarshal([]byte(data), obj2) 83 // println(err2.Error()) 84 assert.Equal(t, err2 == nil, err == nil) 85 // assert.Equal(t, len(data), d.i) 86 assert.Equal(t, obj2, obj) 87 }) 88 89 t.Run("int ", func(t *testing.T) { 90 var obj int = 123 91 var obj2 int = 123 92 var data = `[""]` 93 d := NewDecoder(data) 94 err := d.Decode(&obj) 95 err2 := json.Unmarshal([]byte(data), &obj2) 96 println(err.Error(), obj, obj2) 97 assert.Equal(t, err2 == nil, err == nil) 98 // assert.Equal(t, len(data), d.i) 99 assert.Equal(t, obj2, obj) 100 }) 101 102 t.Run("array", func(t *testing.T) { 103 var obj, obj2 = &[]int{}, &[]int{} 104 var data = `["",true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]` 105 d := NewDecoder(data) 106 err := d.Decode(obj) 107 err2 := json.Unmarshal([]byte(data), obj2) 108 // println(err2.Error()) 109 assert.Equal(t, err2 == nil, err == nil) 110 // assert.Equal(t, len(data), d.i) 111 assert.Equal(t, obj2, obj) 112 }) 113 114 t.Run("map", func(t *testing.T) { 115 var obj, obj2 = &map[int]int{}, &map[int]int{} 116 var data = `{"true" : { },"1":1,"2" : true,"3":3}` 117 d := NewDecoder(data) 118 err := d.Decode(obj) 119 err2 := json.Unmarshal([]byte(data), obj2) 120 assert.Equal(t, err2 == nil, err == nil) 121 // assert.Equal(t, len(data), d.i) 122 assert.Equal(t, obj2, obj) 123 }) 124 t.Run("map error", func(t *testing.T) { 125 var obj, obj2 = &map[int]int{}, &map[int]int{} 126 var data = `{"true" : { ],"1":1,"2" : true,"3":3}` 127 d := NewDecoder(data) 128 err := d.Decode(obj) 129 err2 := json.Unmarshal([]byte(data), obj2) 130 println(err.Error()) 131 println(err2.Error()) 132 assert.Equal(t, err2 == nil, err == nil) 133 // assert.Equal(t, len(data), d.i) 134 // assert.Equal(t, obj2, obj) 135 }) 136 } 137 138 func TestCopyString(t *testing.T) { 139 var data []byte 140 var dc *Decoder 141 var err error 142 data = []byte(`{"A":"0","B":"1"}`) 143 dc = NewDecoder(rt.Mem2Str(data)) 144 dc.UseNumber() 145 dc.CopyString() 146 var obj struct { 147 A string 148 B string 149 } 150 err = dc.Decode(&obj) 151 if err != nil { 152 t.Fatal(err) 153 } 154 data[6] = '1' 155 if obj.A != "0" { 156 t.Fatal(obj) 157 } 158 data[14] = '0' 159 if obj.B != "1" { 160 t.Fatal(obj) 161 } 162 163 data = []byte(`{"A":"0","B":"1"}`) 164 dc = NewDecoder(rt.Mem2Str(data)) 165 dc.UseNumber() 166 err = dc.Decode(&obj) 167 if err != nil { 168 t.Fatal(err) 169 } 170 data[6] = '1' 171 if obj.A != "1" { 172 t.Fatal(obj) 173 } 174 data[14] = '0' 175 if obj.B != "0" { 176 t.Fatal(obj) 177 } 178 179 data = []byte(`{"A":"0","B":"1"}`) 180 dc = NewDecoder(rt.Mem2Str(data)) 181 dc.UseNumber() 182 dc.CopyString() 183 m := map[string]interface{}{} 184 err = dc.Decode(&m) 185 if err != nil { 186 t.Fatal(err) 187 } 188 data[2] = 'C' 189 data[6] = '1' 190 if m["A"] != "0" { 191 t.Fatal(m) 192 } 193 data[10] = 'D' 194 data[14] = '0' 195 if m["B"] != "1" { 196 t.Fatal(m) 197 } 198 199 data = []byte(`{"A":"0","B":"1"}`) 200 dc = NewDecoder(rt.Mem2Str(data)) 201 dc.UseNumber() 202 m = map[string]interface{}{} 203 err = dc.Decode(&m) 204 if err != nil { 205 t.Fatal(err) 206 } 207 data[6] = '1' 208 if m["A"] != "1" { 209 t.Fatal(m) 210 } 211 data[14] = '0' 212 if m["B"] != "0" { 213 t.Fatal(m) 214 } 215 216 data = []byte(`{"A":"0","B":"1"}`) 217 dc = NewDecoder(rt.Mem2Str(data)) 218 dc.UseNumber() 219 dc.CopyString() 220 var x interface{} 221 err = dc.Decode(&x) 222 if err != nil { 223 t.Fatal(err) 224 } 225 data[2] = 'C' 226 data[6] = '1' 227 m = x.(map[string]interface{}) 228 if m["A"] != "0" { 229 t.Fatal(m) 230 } 231 data[10] = 'D' 232 data[14] = '0' 233 if m["B"] != "1" { 234 t.Fatal(m) 235 } 236 237 data = []byte(`{"A":"0","B":"1"}`) 238 dc = NewDecoder(rt.Mem2Str(data)) 239 dc.UseNumber() 240 var y interface{} 241 err = dc.Decode(&y) 242 if err != nil { 243 t.Fatal(err) 244 } 245 m = y.(map[string]interface{}) 246 data[6] = '1' 247 if m["A"] != "1" { 248 t.Fatal(m) 249 } 250 data[14] = '0' 251 if m["B"] != "0" { 252 t.Fatal(m) 253 } 254 } 255 256 func TestDecoder_SetOption(t *testing.T) { 257 var v interface{} 258 d := NewDecoder("123") 259 d.SetOptions(OptionUseInt64) 260 err := d.Decode(&v) 261 assert.NoError(t, err) 262 assert.Equal(t, v, int64(123)) 263 } 264 265 func BenchmarkSkip_Sonic(b *testing.B) { 266 var data = rt.Str2Mem(TwitterJson) 267 if ret, _ := Skip(data); ret < 0 { 268 b.Fatal() 269 } 270 b.SetBytes(int64(len(TwitterJson))) 271 b.ResetTimer() 272 for i := 0; i < b.N; i++ { 273 _, _ = Skip(data) 274 } 275 }