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  }