github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/decoder/decoder_amd64_test.go (about)

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