1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-20 11:28:49 +02:00

consolidate mor tests

This commit is contained in:
Tao Wen 2018-02-13 23:49:40 +08:00
parent 761ce8cce2
commit 8fa357ab7b
33 changed files with 1132 additions and 1663 deletions

View File

@ -14,3 +14,25 @@ func Test_use_number_for_unmarshal(t *testing.T) {
should.Nil(api.UnmarshalFromString("123", &obj)) should.Nil(api.UnmarshalFromString("123", &obj))
should.Equal(json.Number("123"), obj) should.Equal(json.Number("123"), obj)
} }
func Test_customize_float_marshal(t *testing.T) {
should := require.New(t)
json := jsoniter.Config{MarshalFloatWith6Digits: true}.Froze()
str, err := json.MarshalToString(float32(1.23456789))
should.Nil(err)
should.Equal("1.234568", str)
}
func Test_customize_tag_key(t *testing.T) {
type TestObject struct {
Field string `orm:"field"`
}
should := require.New(t)
json := jsoniter.Config{TagKey: "orm"}.Froze()
str, err := json.MarshalToString(TestObject{"hello"})
should.Nil(err)
should.Equal(`{"field":"hello"}`, str)
}

View File

@ -0,0 +1,101 @@
package test
import (
"testing"
"unsafe"
"time"
"github.com/json-iterator/go"
"github.com/stretchr/testify/require"
"strconv"
)
func Test_customize_type_decoder(t *testing.T) {
t.Skip()
jsoniter.RegisterTypeDecoderFunc("time.Time", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.UTC)
if err != nil {
iter.Error = err
return
}
*((*time.Time)(ptr)) = t
})
//defer jsoniter.ConfigDefault.(*frozenConfig).cleanDecoders()
val := time.Time{}
err := jsoniter.Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val)
if err != nil {
t.Fatal(err)
}
year, month, day := val.Date()
if year != 2016 || month != 12 || day != 5 {
t.Fatal(val)
}
}
func Test_customize_byte_array_encoder(t *testing.T) {
t.Skip()
//jsoniter.ConfigDefault.(*frozenConfig).cleanEncoders()
should := require.New(t)
jsoniter.RegisterTypeEncoderFunc("[]uint8", func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
t := *((*[]byte)(ptr))
stream.WriteString(string(t))
}, nil)
//defer jsoniter.ConfigDefault.(*frozenConfig).cleanEncoders()
val := []byte("abc")
str, err := jsoniter.MarshalToString(val)
should.Nil(err)
should.Equal(`"abc"`, str)
}
func Test_customize_field_decoder(t *testing.T) {
type Tom struct {
field1 string
}
jsoniter.RegisterFieldDecoderFunc("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
})
//defer jsoniter.ConfigDefault.(*frozenConfig).cleanDecoders()
tom := Tom{}
err := jsoniter.Unmarshal([]byte(`{"field1": 100}`), &tom)
if err != nil {
t.Fatal(err)
}
}
func Test_recursive_empty_interface_customization(t *testing.T) {
t.Skip()
var obj interface{}
jsoniter.RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
switch iter.WhatIsNext() {
case jsoniter.NumberValue:
*(*interface{})(ptr) = iter.ReadInt64()
default:
*(*interface{})(ptr) = iter.Read()
}
})
should := require.New(t)
jsoniter.Unmarshal([]byte("[100]"), &obj)
should.Equal([]interface{}{int64(100)}, obj)
}
type MyInterface interface {
Hello() string
}
type MyString string
func (ms MyString) Hello() string {
return string(ms)
}
func Test_read_custom_interface(t *testing.T) {
t.Skip()
should := require.New(t)
var val MyInterface
jsoniter.RegisterTypeDecoderFunc("jsoniter.MyInterface", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
*((*MyInterface)(ptr)) = MyString(iter.ReadString())
})
err := jsoniter.UnmarshalFromString(`"hello"`, &val)
should.Nil(err)
should.Equal("hello", val.Hello())
}

View File

@ -0,0 +1,75 @@
package test
import (
"unsafe"
"strconv"
"testing"
"github.com/stretchr/testify/require"
"github.com/json-iterator/go"
)
type TestObject1 struct {
Field1 string
}
type testExtension struct {
jsoniter.DummyExtension
}
func (extension *testExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
if structDescriptor.Type.String() != "test.TestObject1" {
return
}
binding := structDescriptor.GetField("Field1")
binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
str := *((*string)(ptr))
val, _ := strconv.Atoi(str)
stream.WriteInt(val)
}}
binding.Decoder = &funcDecoder{func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
}}
binding.ToNames = []string{"field-1"}
binding.FromNames = []string{"field-1"}
}
func Test_customize_field_by_extension(t *testing.T) {
should := require.New(t)
cfg := jsoniter.Config{}.Froze()
cfg.RegisterExtension(&testExtension{})
obj := TestObject1{}
err := cfg.UnmarshalFromString(`{"field-1": 100}`, &obj)
should.Nil(err)
should.Equal("100", obj.Field1)
str, err := cfg.MarshalToString(obj)
should.Nil(err)
should.Equal(`{"field-1":100}`, str)
}
type funcDecoder struct {
fun jsoniter.DecoderFunc
}
func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
decoder.fun(ptr, iter)
}
type funcEncoder struct {
fun jsoniter.EncoderFunc
isEmptyFunc func(ptr unsafe.Pointer) bool
}
func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
encoder.fun(ptr, stream)
}
func (encoder *funcEncoder) EncodeInterface(val interface{}, stream *jsoniter.Stream) {
jsoniter.WriteToStream(val, stream, encoder)
}
func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
if encoder.isEmptyFunc == nil {
return false
}
return encoder.isEmptyFunc(ptr)
}

View File

@ -1,113 +0,0 @@
package jsoniter
import (
"bytes"
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
func Test_true(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, `true`)
should.True(iter.ReadBool())
iter = ParseString(ConfigDefault, `true`)
should.Equal(true, iter.Read())
}
func Test_false(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, `false`)
should.False(iter.ReadBool())
}
func Test_write_true_false(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096)
stream.WriteTrue()
stream.WriteFalse()
stream.WriteBool(false)
stream.Flush()
should.Nil(stream.Error)
should.Equal("truefalsefalse", buf.String())
}
func Test_write_val_bool(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096)
stream.WriteVal(true)
should.Equal(stream.Buffered(), 4)
stream.Flush()
should.Equal(stream.Buffered(), 0)
should.Nil(stream.Error)
should.Equal("true", buf.String())
}
func Test_encode_string_bool(t *testing.T) {
type TestObject struct {
Field bool `json:",omitempty,string"`
}
should := require.New(t)
output, err := json.Marshal(TestObject{true})
should.Nil(err)
should.Equal(`{"Field":"true"}`, string(output))
output, err = Marshal(TestObject{true})
should.Nil(err)
should.Equal(`{"Field":"true"}`, string(output))
}
func Test_decode_string_bool(t *testing.T) {
type TestObject struct {
Field bool `json:",omitempty,string"`
}
should := require.New(t)
obj := TestObject{}
err := json.Unmarshal([]byte(`{"Field":"true"}`), &obj)
should.Nil(err)
should.True(obj.Field)
obj = TestObject{}
err = json.Unmarshal([]byte(`{"Field":true}`), &obj)
should.NotNil(err)
obj = TestObject{}
err = Unmarshal([]byte(`{"Field":"true"}`), &obj)
should.Nil(err)
should.True(obj.Field)
obj = TestObject{}
err = Unmarshal([]byte(`{"Field":true}`), &obj)
should.NotNil(err)
}
func Test_bool_can_be_null(t *testing.T) {
type TestData struct {
Field bool `json:"field"`
}
should := require.New(t)
obj := TestData{}
data1 := []byte(`{"field": true}`)
err := Unmarshal(data1, &obj)
should.NoError(err)
should.Equal(true, obj.Field)
data2 := []byte(`{"field": null}`)
err = Unmarshal(data2, &obj)
should.NoError(err)
// Same behavior as stdlib, not touching the existing value.
should.Equal(true, obj.Field)
// Checking stdlib behavior as well
obj2 := TestData{}
err = json.Unmarshal(data1, &obj2)
should.NoError(err)
should.Equal(true, obj2.Field)
err = json.Unmarshal(data2, &obj2)
should.NoError(err)
should.Equal(true, obj2.Field)
}

View File

@ -1,342 +0,0 @@
package jsoniter
import (
"encoding/json"
"strconv"
"testing"
"time"
"unsafe"
"github.com/stretchr/testify/require"
)
func Test_customize_type_decoder(t *testing.T) {
RegisterTypeDecoderFunc("time.Time", func(ptr unsafe.Pointer, iter *Iterator) {
t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.UTC)
if err != nil {
iter.Error = err
return
}
*((*time.Time)(ptr)) = t
})
defer ConfigDefault.(*frozenConfig).cleanDecoders()
val := time.Time{}
err := Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val)
if err != nil {
t.Fatal(err)
}
year, month, day := val.Date()
if year != 2016 || month != 12 || day != 5 {
t.Fatal(val)
}
}
func Test_customize_type_encoder(t *testing.T) {
should := require.New(t)
RegisterTypeEncoderFunc("time.Time", func(ptr unsafe.Pointer, stream *Stream) {
t := *((*time.Time)(ptr))
stream.WriteString(t.UTC().Format("2006-01-02 15:04:05"))
}, nil)
defer ConfigDefault.(*frozenConfig).cleanEncoders()
val := time.Unix(0, 0)
str, err := MarshalToString(val)
should.Nil(err)
should.Equal(`"1970-01-01 00:00:00"`, str)
}
func Test_customize_byte_array_encoder(t *testing.T) {
ConfigDefault.(*frozenConfig).cleanEncoders()
should := require.New(t)
RegisterTypeEncoderFunc("[]uint8", func(ptr unsafe.Pointer, stream *Stream) {
t := *((*[]byte)(ptr))
stream.WriteString(string(t))
}, nil)
defer ConfigDefault.(*frozenConfig).cleanEncoders()
val := []byte("abc")
str, err := MarshalToString(val)
should.Nil(err)
should.Equal(`"abc"`, str)
}
func Test_customize_float_marshal(t *testing.T) {
should := require.New(t)
json := Config{MarshalFloatWith6Digits: true}.Froze()
str, err := json.MarshalToString(float32(1.23456789))
should.Nil(err)
should.Equal("1.234568", str)
}
type Tom struct {
field1 string
}
func Test_customize_field_decoder(t *testing.T) {
RegisterFieldDecoderFunc("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
})
defer ConfigDefault.(*frozenConfig).cleanDecoders()
tom := Tom{}
err := Unmarshal([]byte(`{"field1": 100}`), &tom)
if err != nil {
t.Fatal(err)
}
}
type TestObject1 struct {
Field1 string
}
type testExtension struct {
DummyExtension
}
func (extension *testExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
if structDescriptor.Type.String() != "jsoniter.TestObject1" {
return
}
binding := structDescriptor.GetField("Field1")
binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *Stream) {
str := *((*string)(ptr))
val, _ := strconv.Atoi(str)
stream.WriteInt(val)
}}
binding.Decoder = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
}}
binding.ToNames = []string{"field-1"}
binding.FromNames = []string{"field-1"}
}
func Test_customize_field_by_extension(t *testing.T) {
should := require.New(t)
cfg := Config{}.Froze()
cfg.RegisterExtension(&testExtension{})
obj := TestObject1{}
err := cfg.UnmarshalFromString(`{"field-1": 100}`, &obj)
should.Nil(err)
should.Equal("100", obj.Field1)
str, err := cfg.MarshalToString(obj)
should.Nil(err)
should.Equal(`{"field-1":100}`, str)
}
type timeImplementedMarshaler time.Time
func (obj timeImplementedMarshaler) MarshalJSON() ([]byte, error) {
seconds := time.Time(obj).Unix()
return []byte(strconv.FormatInt(seconds, 10)), nil
}
func Test_marshaler(t *testing.T) {
type TestObject struct {
Field timeImplementedMarshaler
}
should := require.New(t)
val := timeImplementedMarshaler(time.Unix(123, 0))
obj := TestObject{val}
bytes, err := json.Marshal(obj)
should.Nil(err)
should.Equal(`{"Field":123}`, string(bytes))
str, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{"Field":123}`, str)
}
func Test_marshaler_and_encoder(t *testing.T) {
type TestObject struct {
Field *timeImplementedMarshaler
}
ConfigDefault.(*frozenConfig).cleanEncoders()
should := require.New(t)
RegisterTypeEncoderFunc("jsoniter.timeImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) {
stream.WriteString("hello from encoder")
}, nil)
val := timeImplementedMarshaler(time.Unix(123, 0))
obj := TestObject{&val}
bytes, err := json.Marshal(obj)
should.Nil(err)
should.Equal(`{"Field":123}`, string(bytes))
str, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{"Field":"hello from encoder"}`, str)
}
type ObjectImplementedUnmarshaler int
func (obj *ObjectImplementedUnmarshaler) UnmarshalJSON(s []byte) error {
val, _ := strconv.ParseInt(string(s[1:len(s)-1]), 10, 64)
*obj = ObjectImplementedUnmarshaler(val)
return nil
}
func Test_unmarshaler(t *testing.T) {
should := require.New(t)
var obj ObjectImplementedUnmarshaler
err := json.Unmarshal([]byte(` "100" `), &obj)
should.Nil(err)
should.Equal(100, int(obj))
iter := ParseString(ConfigDefault, ` "100" `)
iter.ReadVal(&obj)
should.Nil(err)
should.Equal(100, int(obj))
}
func Test_unmarshaler_and_decoder(t *testing.T) {
type TestObject struct {
Field *ObjectImplementedUnmarshaler
Field2 string
}
ConfigDefault.(*frozenConfig).cleanDecoders()
should := require.New(t)
RegisterTypeDecoderFunc("jsoniter.ObjectImplementedUnmarshaler", func(ptr unsafe.Pointer, iter *Iterator) {
*(*ObjectImplementedUnmarshaler)(ptr) = 10
iter.Skip()
})
obj := TestObject{}
val := ObjectImplementedUnmarshaler(0)
obj.Field = &val
err := json.Unmarshal([]byte(`{"Field":"100"}`), &obj)
should.Nil(err)
should.Equal(100, int(*obj.Field))
err = Unmarshal([]byte(`{"Field":"100"}`), &obj)
should.Nil(err)
should.Equal(10, int(*obj.Field))
}
type tmString string
type tmStruct struct {
String tmString
}
func (s tmStruct) MarshalJSON() ([]byte, error) {
var b []byte
b = append(b, '"')
b = append(b, s.String...)
b = append(b, '"')
return b, nil
}
func Test_marshaler_on_struct(t *testing.T) {
fixed := tmStruct{"hello"}
//json.Marshal(fixed)
Marshal(fixed)
}
type withChan struct {
F2 chan []byte
}
func (q withChan) MarshalJSON() ([]byte, error) {
return []byte(`""`), nil
}
func (q *withChan) UnmarshalJSON(value []byte) error {
return nil
}
func Test_marshal_json_with_chan(t *testing.T) {
type TestObject struct {
F1 withChan
}
should := require.New(t)
output, err := MarshalToString(TestObject{})
should.Nil(err)
should.Equal(`{"F1":""}`, output)
}
type withTime struct {
time.Time
}
func (t *withTime) UnmarshalJSON(b []byte) error {
return nil
}
func (t withTime) MarshalJSON() ([]byte, error) {
return []byte(`"fake"`), nil
}
func Test_marshal_json_with_time(t *testing.T) {
type S1 struct {
F1 withTime
F2 *withTime
}
type TestObject struct {
TF1 S1
}
should := require.New(t)
obj := TestObject{
S1{
F1: withTime{
time.Unix(0, 0),
},
F2: &withTime{
time.Unix(0, 0),
},
},
}
output, err := json.Marshal(obj)
should.Nil(err)
should.Equal(`{"TF1":{"F1":"fake","F2":"fake"}}`, string(output))
output, err = Marshal(obj)
should.Nil(err)
should.Equal(`{"TF1":{"F1":"fake","F2":"fake"}}`, string(output))
obj = TestObject{}
should.Nil(json.Unmarshal([]byte(`{"TF1":{"F1":"fake","F2":"fake"}}`), &obj))
should.NotNil(obj.TF1.F2)
obj = TestObject{}
should.Nil(Unmarshal([]byte(`{"TF1":{"F1":"fake","F2":"fake"}}`), &obj))
should.NotNil(obj.TF1.F2)
}
func Test_customize_tag_key(t *testing.T) {
type TestObject struct {
Field string `orm:"field"`
}
should := require.New(t)
json := Config{TagKey: "orm"}.Froze()
str, err := json.MarshalToString(TestObject{"hello"})
should.Nil(err)
should.Equal(`{"field":"hello"}`, str)
}
func Test_recursive_empty_interface_customization(t *testing.T) {
t.Skip()
var obj interface{}
RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *Iterator) {
switch iter.WhatIsNext() {
case NumberValue:
*(*interface{})(ptr) = iter.ReadInt64()
default:
*(*interface{})(ptr) = iter.Read()
}
})
should := require.New(t)
Unmarshal([]byte("[100]"), &obj)
should.Equal([]interface{}{int64(100)}, obj)
}
type GeoLocation struct {
Id string `json:"id,omitempty" db:"id"`
}
func (p *GeoLocation) MarshalJSON() ([]byte, error) {
return []byte(`{}`), nil
}
func (p *GeoLocation) UnmarshalJSON(input []byte) error {
p.Id = "hello"
return nil
}
func Test_marshal_and_unmarshal_on_non_pointer(t *testing.T) {
should := require.New(t)
locations := []GeoLocation{{"000"}}
bytes, err := Marshal(locations)
should.Nil(err)
should.Equal("[{}]", string(bytes))
err = Unmarshal([]byte("[1]"), &locations)
should.Nil(err)
should.Equal("hello", locations[0].Id)
}

View File

@ -1,87 +0,0 @@
package jsoniter
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
func Test_bind_api_demo(t *testing.T) {
should := require.New(t)
val := []int{}
err := UnmarshalFromString(`[0,1,2,3] `, &val)
should.Nil(err)
should.Equal([]int{0, 1, 2, 3}, val)
}
func Test_iterator_api_demo(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, `[0,1,2,3]`)
total := 0
for iter.ReadArray() {
total += iter.ReadInt()
}
should.Equal(6, total)
}
type People struct {
Name string
Gender string
Age int
Address string
Mobile string
Country string
Height int
}
func jsoniterMarshal(p *People) error {
_, err := Marshal(p)
if nil != err {
return err
}
return nil
}
func stdMarshal(p *People) error {
_, err := json.Marshal(p)
if nil != err {
return err
}
return nil
}
func BenchmarkJosniterMarshal(b *testing.B) {
var p People
p.Address = "上海市徐汇区漕宝路"
p.Age = 30
p.Country = "中国"
p.Gender = "male"
p.Height = 170
p.Mobile = "18502120533"
p.Name = "Elvin"
b.ReportAllocs()
for i := 0; i < b.N; i++ {
err := jsoniterMarshal(&p)
if nil != err {
b.Error(err)
}
}
}
func BenchmarkStdMarshal(b *testing.B) {
var p People
p.Address = "上海市徐汇区漕宝路"
p.Age = 30
p.Country = "中国"
p.Gender = "male"
p.Height = 170
p.Mobile = "18502120533"
p.Name = "Elvin"
b.ReportAllocs()
for i := 0; i < b.N; i++ {
err := stdMarshal(&p)
if nil != err {
b.Error(err)
}
}
}

View File

@ -1,42 +0,0 @@
package jsoniter
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
func Test_encode_interface(t *testing.T) {
should := require.New(t)
var a interface{}
a = int8(10)
str, err := MarshalToString(a)
should.Nil(err)
should.Equal(str, "10")
a = float32(3)
str, err = MarshalToString(a)
should.Nil(err)
should.Equal(str, "3")
a = map[string]interface{}{"abc": 1}
str, err = MarshalToString(a)
should.Nil(err)
should.Equal(str, `{"abc":1}`)
a = uintptr(1)
str, err = MarshalToString(a)
should.Nil(err)
should.Equal(str, "1")
a = uint(1)
str, err = MarshalToString(a)
should.Nil(err)
should.Equal(str, "1")
a = uint8(1)
str, err = MarshalToString(a)
should.Nil(err)
should.Equal(str, "1")
a = json.RawMessage("abc")
MarshalToString(a)
str, err = MarshalToString(a)
should.Nil(err)
should.Equal(str, "abc")
}

View File

@ -1,50 +0,0 @@
package jsoniter
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
type MyEnum int64
const (
MyEnumA MyEnum = iota
MyEnumB
)
func (m *MyEnum) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"foo-%d"`, int(*m))), nil
}
func (m *MyEnum) UnmarshalJSON(jb []byte) error {
switch string(jb) {
case `"foo-1"`:
*m = MyEnumB
default:
*m = MyEnumA
}
return nil
}
func Test_custom_marshaler_on_enum(t *testing.T) {
type Wrapper struct {
Payload interface{}
}
type Wrapper2 struct {
Payload MyEnum
}
should := require.New(t)
w := Wrapper{Payload: MyEnumB}
jb, err := Marshal(w)
should.NoError(err)
should.Equal(`{"Payload":"foo-1"}`, string(jb))
var w2 Wrapper2
err = Unmarshal(jb, &w2)
should.NoError(err)
should.Equal(MyEnumB, w2.Payload)
}

View File

@ -1,46 +0,0 @@
package jsoniter
import (
"encoding/json"
"github.com/stretchr/testify/require"
"testing"
)
func Test_encode_fixed_array(t *testing.T) {
should := require.New(t)
type FixedArray [2]float64
fixed := FixedArray{0.1, 1.0}
output, err := MarshalToString(fixed)
should.Nil(err)
should.Equal("[0.1,1]", output)
}
func Test_encode_fixed_array_empty(t *testing.T) {
should := require.New(t)
type FixedArray [0]float64
fixed := FixedArray{}
output, err := MarshalToString(fixed)
should.Nil(err)
should.Equal("[]", output)
}
func Test_encode_fixed_array_of_map(t *testing.T) {
should := require.New(t)
type FixedArray [2]map[string]string
fixed := FixedArray{map[string]string{"1": "2"}, map[string]string{"3": "4"}}
output, err := MarshalToString(fixed)
should.Nil(err)
should.Equal(`[{"1":"2"},{"3":"4"}]`, output)
}
func Test_decode_fixed_array(t *testing.T) {
should := require.New(t)
type FixedArray [2]float64
var fixed FixedArray
should.Nil(json.Unmarshal([]byte("[1,2,3]"), &fixed))
should.Equal(float64(1), fixed[0])
should.Equal(float64(2), fixed[1])
should.Nil(Unmarshal([]byte("[1,2,3]"), &fixed))
should.Equal(float64(1), fixed[0])
should.Equal(float64(2), fixed[1])
}

View File

@ -1,576 +0,0 @@
package jsoniter
import (
"encoding/json"
"fmt"
"testing"
"unsafe"
"github.com/stretchr/testify/require"
"reflect"
)
func Test_write_empty_interface_via_placeholder(t *testing.T) {
fmt.Println(^uint(0) >> 1)
should := require.New(t)
m := map[uint32]interface{}{1: "hello"}
inf := reflect.ValueOf(m).MapIndex(reflect.ValueOf(uint32(1))).Interface()
encoder := &placeholderEncoder{
cfg: ConfigFastest.(*frozenConfig),
cacheKey: reflect.TypeOf(m).Elem(),
}
stream := ConfigFastest.BorrowStream(nil)
encoderOfType(ConfigFastest.(*frozenConfig), "", reflect.TypeOf(m).Elem())
encoder.EncodeInterface(inf, stream)
should.Equal(`"hello"`, string(stream.Buffer()))
}
func Test_write_array_of_interface(t *testing.T) {
should := require.New(t)
array := []interface{}{"hello"}
str, err := MarshalToString(array)
should.Nil(err)
should.Equal(`["hello"]`, str)
}
func Test_write_map_of_interface(t *testing.T) {
should := require.New(t)
val := map[string]interface{}{"hello": "world"}
str, err := MarshalToString(val)
should.Nil(err)
should.Equal(`{"hello":"world"}`, str)
}
func Test_write_map_of_interface_in_struct(t *testing.T) {
type TestObject struct {
Field map[string]interface{}
}
should := require.New(t)
val := TestObject{map[string]interface{}{"hello": "world"}}
str, err := MarshalToString(val)
should.Nil(err)
should.Equal(`{"Field":{"hello":"world"}}`, str)
}
func Test_write_map_of_interface_in_struct_with_two_fields(t *testing.T) {
type TestObject struct {
Field map[string]interface{}
Field2 string
}
should := require.New(t)
val := TestObject{map[string]interface{}{"hello": "world"}, ""}
str, err := MarshalToString(val)
should.Nil(err)
should.Contains(str, `"Field":{"hello":"world"}`)
}
type MyInterface interface {
Hello() string
}
type MyString string
func (ms MyString) Hello() string {
return string(ms)
}
func Test_write_map_of_custom_interface(t *testing.T) {
should := require.New(t)
myStr := MyString("world")
should.Equal("world", myStr.Hello())
val := map[string]MyInterface{"hello": myStr}
str, err := MarshalToString(val)
should.Nil(err)
should.Equal(`{"hello":"world"}`, str)
}
func Test_write_interface(t *testing.T) {
should := require.New(t)
var val interface{}
val = "hello"
str, err := MarshalToString(val)
should.Nil(err)
should.Equal(`"hello"`, str)
}
func Test_read_interface(t *testing.T) {
should := require.New(t)
var val interface{}
err := UnmarshalFromString(`"hello"`, &val)
should.Nil(err)
should.Equal("hello", val)
err = UnmarshalFromString(`1e1`, &val)
should.Nil(err)
should.Equal(float64(10), val)
err = UnmarshalFromString(`1.0e1`, &val)
should.Nil(err)
should.Equal(float64(10), val)
err = json.Unmarshal([]byte(`1.0e1`), &val)
should.Nil(err)
should.Equal(float64(10), val)
}
func Test_read_custom_interface(t *testing.T) {
should := require.New(t)
var val MyInterface
RegisterTypeDecoderFunc("jsoniter.MyInterface", func(ptr unsafe.Pointer, iter *Iterator) {
*((*MyInterface)(ptr)) = MyString(iter.ReadString())
})
err := UnmarshalFromString(`"hello"`, &val)
should.Nil(err)
should.Equal("hello", val.Hello())
}
func Test_decode_object_contain_empty_interface(t *testing.T) {
type TestObject struct {
Field interface{}
}
should := require.New(t)
obj := TestObject{}
obj.Field = 1024
should.Nil(UnmarshalFromString(`{"Field": "hello"}`, &obj))
should.Equal("hello", obj.Field)
}
func Test_decode_object_contain_non_empty_interface(t *testing.T) {
type TestObject struct {
Field MyInterface
}
should := require.New(t)
obj := TestObject{}
obj.Field = MyString("abc")
should.Nil(UnmarshalFromString(`{"Field": "hello"}`, &obj))
should.Equal(MyString("hello"), obj.Field)
}
func Test_encode_object_contain_empty_interface(t *testing.T) {
type TestObject struct {
Field interface{}
}
should := require.New(t)
obj := TestObject{}
obj.Field = 1024
str, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{"Field":1024}`, str)
}
func Test_encode_object_contain_non_empty_interface(t *testing.T) {
type TestObject struct {
Field MyInterface
}
should := require.New(t)
obj := TestObject{}
obj.Field = MyString("hello")
str, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{"Field":"hello"}`, str)
}
func Test_nil_non_empty_interface(t *testing.T) {
ConfigDefault.(*frozenConfig).cleanEncoders()
ConfigDefault.(*frozenConfig).cleanDecoders()
type TestObject struct {
Field []MyInterface
}
should := require.New(t)
obj := TestObject{}
b := []byte(`{"Field":["AAA"]}`)
should.NotNil(json.Unmarshal(b, &obj))
should.NotNil(Unmarshal(b, &obj))
}
func Test_read_large_number_as_interface(t *testing.T) {
should := require.New(t)
var val interface{}
err := Config{UseNumber: true}.Froze().UnmarshalFromString(`123456789123456789123456789`, &val)
should.Nil(err)
output, err := MarshalToString(val)
should.Nil(err)
should.Equal(`123456789123456789123456789`, output)
}
func Test_nested_one_field_struct(t *testing.T) {
should := require.New(t)
type YetYetAnotherObject struct {
Field string
}
type YetAnotherObject struct {
Field *YetYetAnotherObject
}
type AnotherObject struct {
Field *YetAnotherObject
}
type TestObject struct {
Me *AnotherObject
}
obj := TestObject{&AnotherObject{&YetAnotherObject{&YetYetAnotherObject{"abc"}}}}
str, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str)
str, err = MarshalToString(&obj)
should.Nil(err)
should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str)
}
func Test_struct_with_embedded_ptr_with_tag(t *testing.T) {
type O1 struct {
O1F string
}
type Option struct {
O1 *O1
}
type T struct {
Option `json:","`
}
var obj T
should := require.New(t)
output, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{"O1":null}`, output)
}
func Test_struct_with_one_nil(t *testing.T) {
type TestObject struct {
F *float64
}
var obj TestObject
should := require.New(t)
output, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{"F":null}`, output)
}
func Test_struct_with_one_nil_embedded(t *testing.T) {
type Parent struct {
Field1 string
Field2 string
}
type TestObject struct {
*Parent
}
obj := TestObject{}
should := require.New(t)
bytes, err := json.Marshal(obj)
should.Nil(err)
should.Equal("{}", string(bytes))
output, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`{}`, output)
}
func Test_struct_with_not_nil_embedded(t *testing.T) {
type Parent struct {
Field0 string
Field1 []string
Field2 map[string]interface{}
}
type TestObject struct {
*Parent
}
should := require.New(t)
var obj TestObject
err := UnmarshalFromString(`{"Field0":"1","Field1":null,"Field2":{"K":"V"}}`, &obj)
should.Nil(err)
should.Nil(obj.Field1)
should.Equal(map[string]interface{}{"K": "V"}, obj.Field2)
should.Equal("1", obj.Field0)
}
func Test_array_with_one_nil_ptr(t *testing.T) {
obj := [1]*float64{nil}
should := require.New(t)
output, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`[null]`, output)
}
func Test_array_with_one_not_nil_ptr(t *testing.T) {
two := float64(2)
obj := [1]*float64{&two}
should := require.New(t)
output, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`[2]`, output)
}
func Test_embedded_array_with_one_nil(t *testing.T) {
type TestObject struct {
Field1 int
Field2 [1]*float64
}
var obj TestObject
should := require.New(t)
output, err := MarshalToString(obj)
should.Nil(err)
should.Contains(output, `"Field2":[null]`)
}
func Test_array_with_nothing(t *testing.T) {
var obj [2]*float64
should := require.New(t)
output, err := MarshalToString(obj)
should.Nil(err)
should.Equal(`[null,null]`, output)
}
func Test_unmarshal_ptr_to_interface(t *testing.T) {
type TestData struct {
Name string `json:"name"`
}
should := require.New(t)
var obj interface{} = &TestData{}
err := json.Unmarshal([]byte(`{"name":"value"}`), &obj)
should.Nil(err)
should.Equal("&{value}", fmt.Sprintf("%v", obj))
obj = interface{}(&TestData{})
err = Unmarshal([]byte(`{"name":"value"}`), &obj)
should.Nil(err)
should.Equal("&{value}", fmt.Sprintf("%v", obj))
}
func Test_nil_out_null_interface(t *testing.T) {
type TestData struct {
Field interface{} `json:"field"`
}
should := require.New(t)
var boolVar bool
obj := TestData{
Field: &boolVar,
}
data1 := []byte(`{"field": true}`)
err := Unmarshal(data1, &obj)
should.NoError(err)
should.Equal(true, *(obj.Field.(*bool)))
data2 := []byte(`{"field": null}`)
err = Unmarshal(data2, &obj)
should.NoError(err)
should.Equal(nil, obj.Field)
// Checking stdlib behavior matches.
obj2 := TestData{
Field: &boolVar,
}
err = json.Unmarshal(data1, &obj2)
should.NoError(err)
should.Equal(true, *(obj2.Field.(*bool)))
err = json.Unmarshal(data2, &obj2)
should.NoError(err)
should.Equal(nil, obj2.Field)
}
func Test_omitempty_nil_interface(t *testing.T) {
type TestData struct {
Field interface{} `json:"field,omitempty"`
}
should := require.New(t)
obj := TestData{
Field: nil,
}
js, err := json.Marshal(obj)
should.NoError(err)
should.Equal("{}", string(js))
str, err := MarshalToString(obj)
should.NoError(err)
should.Equal(string(js), str)
}
func Test_omitempty_nil_nonempty_interface(t *testing.T) {
type TestData struct {
Field MyInterface `json:"field,omitempty"`
}
should := require.New(t)
obj := TestData{
Field: nil,
}
js, err := json.Marshal(obj)
should.NoError(err)
should.Equal("{}", string(js))
str, err := MarshalToString(obj)
should.NoError(err)
should.Equal(string(js), str)
obj.Field = MyString("hello")
err = UnmarshalFromString(`{"field":null}`, &obj)
should.NoError(err)
should.Nil(obj.Field)
}
func Test_marshal_nil_marshaler_interface(t *testing.T) {
type TestData struct {
Field json.Marshaler `json:"field"`
}
should := require.New(t)
obj := TestData{
Field: nil,
}
js, err := json.Marshal(obj)
should.NoError(err)
should.Equal(`{"field":null}`, string(js))
str, err := MarshalToString(obj)
should.NoError(err)
should.Equal(string(js), str)
}
func Test_marshal_nil_nonempty_interface(t *testing.T) {
type TestData struct {
Field MyInterface `json:"field"`
}
should := require.New(t)
obj := TestData{
Field: nil,
}
js, err := json.Marshal(obj)
should.NoError(err)
should.Equal(`{"field":null}`, string(js))
str, err := MarshalToString(obj)
should.NoError(err)
should.Equal(string(js), str)
obj.Field = MyString("hello")
err = Unmarshal(js, &obj)
should.NoError(err)
should.Equal(nil, obj.Field)
}
func Test_overwrite_interface_ptr_value_with_nil(t *testing.T) {
type Wrapper struct {
Payload interface{} `json:"payload,omitempty"`
}
type Payload struct {
Value int `json:"val,omitempty"`
}
should := require.New(t)
payload := &Payload{}
wrapper := &Wrapper{
Payload: &payload,
}
err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal((*Payload)(nil), payload)
payload = &Payload{}
wrapper = &Wrapper{
Payload: &payload,
}
err = Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
err = Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal((*Payload)(nil), payload)
}
func Test_overwrite_interface_value_with_nil(t *testing.T) {
type Wrapper struct {
Payload interface{} `json:"payload,omitempty"`
}
type Payload struct {
Value int `json:"val,omitempty"`
}
should := require.New(t)
payload := &Payload{}
wrapper := &Wrapper{
Payload: payload,
}
err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(42, (*(wrapper.Payload.(*Payload))).Value)
err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(nil, wrapper.Payload)
should.Equal(42, payload.Value)
payload = &Payload{}
wrapper = &Wrapper{
Payload: payload,
}
err = Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(42, (*(wrapper.Payload.(*Payload))).Value)
err = Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(nil, wrapper.Payload)
should.Equal(42, payload.Value)
}
func Test_unmarshal_into_nil(t *testing.T) {
type Payload struct {
Value int `json:"val,omitempty"`
}
type Wrapper struct {
Payload interface{} `json:"payload,omitempty"`
}
should := require.New(t)
var payload *Payload
wrapper := &Wrapper{
Payload: payload,
}
err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Nil(err)
should.NotNil(wrapper.Payload)
should.Nil(payload)
err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Nil(err)
should.Nil(wrapper.Payload)
should.Nil(payload)
payload = nil
wrapper = &Wrapper{
Payload: payload,
}
err = Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Nil(err)
should.NotNil(wrapper.Payload)
should.Nil(payload)
err = Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Nil(err)
should.Nil(wrapper.Payload)
should.Nil(payload)
}

View File

@ -1,19 +1,20 @@
package jsoniter package misc_tests
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"testing" "testing"
"github.com/json-iterator/go"
) )
func Test_empty_array(t *testing.T) { func Test_empty_array(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, `[]`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[]`)
cont := iter.ReadArray() cont := iter.ReadArray()
should.False(cont) should.False(cont)
iter = ParseString(ConfigDefault, `[]`) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[]`)
iter.ReadArrayCB(func(iter *Iterator) bool { iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool {
should.FailNow("should not call") should.FailNow("should not call")
return true return true
}) })
@ -21,12 +22,12 @@ func Test_empty_array(t *testing.T) {
func Test_one_element(t *testing.T) { func Test_one_element(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, `[1]`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1]`)
should.True(iter.ReadArray()) should.True(iter.ReadArray())
should.Equal(1, iter.ReadInt()) should.Equal(1, iter.ReadInt())
should.False(iter.ReadArray()) should.False(iter.ReadArray())
iter = ParseString(ConfigDefault, `[1]`) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[1]`)
iter.ReadArrayCB(func(iter *Iterator) bool { iter.ReadArrayCB(func(iter *jsoniter.Iterator) bool {
should.Equal(1, iter.ReadInt()) should.Equal(1, iter.ReadInt())
return true return true
}) })
@ -34,18 +35,18 @@ func Test_one_element(t *testing.T) {
func Test_two_elements(t *testing.T) { func Test_two_elements(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, `[1,2]`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1,2]`)
should.True(iter.ReadArray()) should.True(iter.ReadArray())
should.Equal(int64(1), iter.ReadInt64()) should.Equal(int64(1), iter.ReadInt64())
should.True(iter.ReadArray()) should.True(iter.ReadArray())
should.Equal(int64(2), iter.ReadInt64()) should.Equal(int64(2), iter.ReadInt64())
should.False(iter.ReadArray()) should.False(iter.ReadArray())
iter = ParseString(ConfigDefault, `[1,2]`) iter = jsoniter.ParseString(jsoniter.ConfigDefault, `[1,2]`)
should.Equal([]interface{}{float64(1), float64(2)}, iter.Read()) should.Equal([]interface{}{float64(1), float64(2)}, iter.Read())
} }
func Test_whitespace_in_head(t *testing.T) { func Test_whitespace_in_head(t *testing.T) {
iter := ParseString(ConfigDefault, ` [1]`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, ` [1]`)
cont := iter.ReadArray() cont := iter.ReadArray()
if cont != true { if cont != true {
t.FailNow() t.FailNow()
@ -56,7 +57,7 @@ func Test_whitespace_in_head(t *testing.T) {
} }
func Test_whitespace_after_array_start(t *testing.T) { func Test_whitespace_after_array_start(t *testing.T) {
iter := ParseString(ConfigDefault, `[ 1]`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[ 1]`)
cont := iter.ReadArray() cont := iter.ReadArray()
if cont != true { if cont != true {
t.FailNow() t.FailNow()
@ -67,7 +68,7 @@ func Test_whitespace_after_array_start(t *testing.T) {
} }
func Test_whitespace_before_array_end(t *testing.T) { func Test_whitespace_before_array_end(t *testing.T) {
iter := ParseString(ConfigDefault, `[1 ]`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1 ]`)
cont := iter.ReadArray() cont := iter.ReadArray()
if cont != true { if cont != true {
t.FailNow() t.FailNow()
@ -82,7 +83,7 @@ func Test_whitespace_before_array_end(t *testing.T) {
} }
func Test_whitespace_before_comma(t *testing.T) { func Test_whitespace_before_comma(t *testing.T) {
iter := ParseString(ConfigDefault, `[1 ,2]`) iter := jsoniter.ParseString(jsoniter.ConfigDefault, `[1 ,2]`)
cont := iter.ReadArray() cont := iter.ReadArray()
if cont != true { if cont != true {
t.FailNow() t.FailNow()
@ -106,7 +107,7 @@ func Test_whitespace_before_comma(t *testing.T) {
func Test_write_array(t *testing.T) { func Test_write_array(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(Config{IndentionStep: 2}.Froze(), buf, 4096) stream := jsoniter.NewStream(jsoniter.Config{IndentionStep: 2}.Froze(), buf, 4096)
stream.WriteArrayStart() stream.WriteArrayStart()
stream.WriteInt(1) stream.WriteInt(1)
stream.WriteMore() stream.WriteMore()
@ -120,7 +121,7 @@ func Test_write_array(t *testing.T) {
func Test_write_val_array(t *testing.T) { func Test_write_val_array(t *testing.T) {
should := require.New(t) should := require.New(t)
val := []int{1, 2, 3} val := []int{1, 2, 3}
str, err := MarshalToString(&val) str, err := jsoniter.MarshalToString(&val)
should.Nil(err) should.Nil(err)
should.Equal("[1,2,3]", str) should.Equal("[1,2,3]", str)
} }
@ -128,7 +129,7 @@ func Test_write_val_array(t *testing.T) {
func Test_write_val_empty_array(t *testing.T) { func Test_write_val_empty_array(t *testing.T) {
should := require.New(t) should := require.New(t)
val := []int{} val := []int{}
str, err := MarshalToString(val) str, err := jsoniter.MarshalToString(val)
should.Nil(err) should.Nil(err)
should.Equal("[]", str) should.Equal("[]", str)
} }
@ -140,7 +141,7 @@ func Test_write_array_of_interface_in_struct(t *testing.T) {
Field2 string Field2 string
} }
val := TestObject{[]interface{}{1, 2}, ""} val := TestObject{[]interface{}{1, 2}, ""}
str, err := MarshalToString(val) str, err := jsoniter.MarshalToString(val)
should.Nil(err) should.Nil(err)
should.Contains(str, `"Field":[1,2]`) should.Contains(str, `"Field":[1,2]`)
should.Contains(str, `"Field2":""`) should.Contains(str, `"Field2":""`)
@ -151,7 +152,7 @@ func Test_encode_byte_array(t *testing.T) {
bytes, err := json.Marshal([]byte{1, 2, 3}) bytes, err := json.Marshal([]byte{1, 2, 3})
should.Nil(err) should.Nil(err)
should.Equal(`"AQID"`, string(bytes)) should.Equal(`"AQID"`, string(bytes))
bytes, err = Marshal([]byte{1, 2, 3}) bytes, err = jsoniter.Marshal([]byte{1, 2, 3})
should.Nil(err) should.Nil(err)
should.Equal(`"AQID"`, string(bytes)) should.Equal(`"AQID"`, string(bytes))
} }
@ -162,7 +163,7 @@ func Test_decode_byte_array_from_base64(t *testing.T) {
err := json.Unmarshal([]byte(`"AQID"`), &data) err := json.Unmarshal([]byte(`"AQID"`), &data)
should.Nil(err) should.Nil(err)
should.Equal([]byte{1, 2, 3}, data) should.Equal([]byte{1, 2, 3}, data)
err = Unmarshal([]byte(`"AQID"`), &data) err = jsoniter.Unmarshal([]byte(`"AQID"`), &data)
should.Nil(err) should.Nil(err)
should.Equal([]byte{1, 2, 3}, data) should.Equal([]byte{1, 2, 3}, data)
} }
@ -173,7 +174,7 @@ func Test_decode_byte_array_from_array(t *testing.T) {
err := json.Unmarshal([]byte(`[1,2,3]`), &data) err := json.Unmarshal([]byte(`[1,2,3]`), &data)
should.Nil(err) should.Nil(err)
should.Equal([]byte{1, 2, 3}, data) should.Equal([]byte{1, 2, 3}, data)
err = Unmarshal([]byte(`[1,2,3]`), &data) err = jsoniter.Unmarshal([]byte(`[1,2,3]`), &data)
should.Nil(err) should.Nil(err)
should.Equal([]byte{1, 2, 3}, data) should.Equal([]byte{1, 2, 3}, data)
} }
@ -181,21 +182,21 @@ func Test_decode_byte_array_from_array(t *testing.T) {
func Test_decode_slice(t *testing.T) { func Test_decode_slice(t *testing.T) {
should := require.New(t) should := require.New(t)
slice := make([]string, 0, 5) slice := make([]string, 0, 5)
UnmarshalFromString(`["hello", "world"]`, &slice) jsoniter.UnmarshalFromString(`["hello", "world"]`, &slice)
should.Equal([]string{"hello", "world"}, slice) should.Equal([]string{"hello", "world"}, slice)
} }
func Test_decode_large_slice(t *testing.T) { func Test_decode_large_slice(t *testing.T) {
should := require.New(t) should := require.New(t)
slice := make([]int, 0, 1) slice := make([]int, 0, 1)
UnmarshalFromString(`[1,2,3,4,5,6,7,8,9]`, &slice) jsoniter.UnmarshalFromString(`[1,2,3,4,5,6,7,8,9]`, &slice)
should.Equal([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, slice) should.Equal([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, slice)
} }
func Benchmark_jsoniter_array(b *testing.B) { func Benchmark_jsoniter_array(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
input := []byte(`[1,2,3,4,5,6,7,8,9]`) input := []byte(`[1,2,3,4,5,6,7,8,9]`)
iter := ParseBytes(ConfigDefault, input) iter := jsoniter.ParseBytes(jsoniter.ConfigDefault, input)
b.ResetTimer() b.ResetTimer()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
iter.ResetBytes(input) iter.ResetBytes(input)

View File

@ -0,0 +1,47 @@
package misc_tests
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
"github.com/json-iterator/go"
)
func Test_true(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, `true`)
should.True(iter.ReadBool())
iter = jsoniter.ParseString(jsoniter.ConfigDefault, `true`)
should.Equal(true, iter.Read())
}
func Test_false(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, `false`)
should.False(iter.ReadBool())
}
func Test_write_true_false(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteTrue()
stream.WriteFalse()
stream.WriteBool(false)
stream.Flush()
should.Nil(stream.Error)
should.Equal("truefalsefalse", buf.String())
}
func Test_write_val_bool(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(true)
should.Equal(stream.Buffered(), 4)
stream.Flush()
should.Equal(stream.Buffered(), 0)
should.Nil(stream.Error)
should.Equal("true", buf.String())
}

View File

@ -0,0 +1,95 @@
package misc_tests
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
"github.com/json-iterator/go"
)
func Test_read_big_float(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, `12.3`)
val := iter.ReadBigFloat()
val64, _ := val.Float64()
should.Equal(12.3, val64)
}
func Test_read_big_int(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, `92233720368547758079223372036854775807`)
val := iter.ReadBigInt()
should.NotNil(val)
should.Equal(`92233720368547758079223372036854775807`, val.String())
}
func Test_read_float_as_interface(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, `12.3`)
should.Equal(float64(12.3), iter.Read())
}
func Test_wrap_float(t *testing.T) {
should := require.New(t)
str, err := jsoniter.MarshalToString(jsoniter.WrapFloat64(12.3))
should.Nil(err)
should.Equal("12.3", str)
}
func Test_read_float64_cursor(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, "[1.23456789\n,2,3]")
should.True(iter.ReadArray())
should.Equal(1.23456789, iter.Read())
should.True(iter.ReadArray())
should.Equal(float64(2), iter.Read())
}
func Test_read_float_scientific(t *testing.T) {
should := require.New(t)
var obj interface{}
should.Nil(jsoniter.UnmarshalFromString(`1e1`, &obj))
should.Equal(float64(10), obj)
should.Nil(json.Unmarshal([]byte(`1e1`), &obj))
should.Equal(float64(10), obj)
should.Nil(jsoniter.UnmarshalFromString(`1.0e1`, &obj))
should.Equal(float64(10), obj)
should.Nil(json.Unmarshal([]byte(`1.0e1`), &obj))
should.Equal(float64(10), obj)
}
func Test_lossy_float_marshal(t *testing.T) {
should := require.New(t)
api := jsoniter.Config{MarshalFloatWith6Digits: true}.Froze()
output, err := api.MarshalToString(float64(0.1234567))
should.Nil(err)
should.Equal("0.123457", output)
output, err = api.MarshalToString(float32(0.1234567))
should.Nil(err)
should.Equal("0.123457", output)
}
func Test_read_number(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, `92233720368547758079223372036854775807`)
val := iter.ReadNumber()
should.Equal(`92233720368547758079223372036854775807`, string(val))
}
func Benchmark_jsoniter_float(b *testing.B) {
b.ReportAllocs()
input := []byte(`1.1123,`)
iter := jsoniter.NewIterator(jsoniter.ConfigDefault)
for n := 0; n < b.N; n++ {
iter.ResetBytes(input)
iter.ReadFloat64()
}
}
func Benchmark_json_float(b *testing.B) {
for n := 0; n < b.N; n++ {
result := float64(0)
json.Unmarshal([]byte(`1.1`), &result)
}
}

View File

@ -0,0 +1,101 @@
// +build go1.8
package misc_tests
import (
"bytes"
"encoding/json"
"io/ioutil"
"strconv"
"testing"
"github.com/stretchr/testify/require"
"github.com/json-iterator/go"
)
func Test_read_uint64_invalid(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, ",")
iter.ReadUint64()
should.NotNil(iter.Error)
}
func Test_read_int32_array(t *testing.T) {
should := require.New(t)
input := `[123,456,789]`
val := make([]int32, 0)
jsoniter.UnmarshalFromString(input, &val)
should.Equal(3, len(val))
}
func Test_read_int64_array(t *testing.T) {
should := require.New(t)
input := `[123,456,789]`
val := make([]int64, 0)
jsoniter.UnmarshalFromString(input, &val)
should.Equal(3, len(val))
}
func Test_wrap_int(t *testing.T) {
should := require.New(t)
str, err := jsoniter.MarshalToString(jsoniter.WrapInt64(100))
should.Nil(err)
should.Equal("100", str)
}
func Test_write_val_int(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(1001)
stream.Flush()
should.Nil(stream.Error)
should.Equal("1001", buf.String())
}
func Test_write_val_int_ptr(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
val := 1001
stream.WriteVal(&val)
stream.Flush()
should.Nil(stream.Error)
should.Equal("1001", buf.String())
}
func Test_float_as_int(t *testing.T) {
should := require.New(t)
var i int
should.NotNil(jsoniter.Unmarshal([]byte(`1.1`), &i))
}
func Benchmark_jsoniter_encode_int(b *testing.B) {
stream := jsoniter.NewStream(jsoniter.ConfigDefault, ioutil.Discard, 64)
for n := 0; n < b.N; n++ {
stream.Reset(nil)
stream.WriteUint64(0xffffffff)
}
}
func Benchmark_itoa(b *testing.B) {
for n := 0; n < b.N; n++ {
strconv.FormatInt(0xffffffff, 10)
}
}
func Benchmark_jsoniter_int(b *testing.B) {
iter := jsoniter.NewIterator(jsoniter.ConfigDefault)
input := []byte(`100`)
for n := 0; n < b.N; n++ {
iter.ResetBytes(input)
iter.ReadInt64()
}
}
func Benchmark_json_int(b *testing.B) {
for n := 0; n < b.N; n++ {
result := int64(0)
json.Unmarshal([]byte(`-100`), &result)
}
}

View File

@ -0,0 +1,224 @@
package misc_tests
import (
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/require"
"github.com/json-iterator/go"
)
type MyInterface interface {
Hello() string
}
type MyString string
func (ms MyString) Hello() string {
return string(ms)
}
func Test_decode_object_contain_non_empty_interface(t *testing.T) {
type TestObject struct {
Field MyInterface
}
should := require.New(t)
obj := TestObject{}
obj.Field = MyString("abc")
should.Nil(jsoniter.UnmarshalFromString(`{"Field": "hello"}`, &obj))
should.Equal(MyString("hello"), obj.Field)
}
func Test_nil_non_empty_interface(t *testing.T) {
type TestObject struct {
Field []MyInterface
}
should := require.New(t)
obj := TestObject{}
b := []byte(`{"Field":["AAA"]}`)
should.NotNil(json.Unmarshal(b, &obj))
should.NotNil(jsoniter.Unmarshal(b, &obj))
}
func Test_read_large_number_as_interface(t *testing.T) {
should := require.New(t)
var val interface{}
err := jsoniter.Config{UseNumber: true}.Froze().UnmarshalFromString(`123456789123456789123456789`, &val)
should.Nil(err)
output, err := jsoniter.MarshalToString(val)
should.Nil(err)
should.Equal(`123456789123456789123456789`, output)
}
func Test_unmarshal_ptr_to_interface(t *testing.T) {
type TestData struct {
Name string `json:"name"`
}
should := require.New(t)
var obj interface{} = &TestData{}
err := json.Unmarshal([]byte(`{"name":"value"}`), &obj)
should.Nil(err)
should.Equal("&{value}", fmt.Sprintf("%v", obj))
obj = interface{}(&TestData{})
err = jsoniter.Unmarshal([]byte(`{"name":"value"}`), &obj)
should.Nil(err)
should.Equal("&{value}", fmt.Sprintf("%v", obj))
}
func Test_nil_out_null_interface(t *testing.T) {
type TestData struct {
Field interface{} `json:"field"`
}
should := require.New(t)
var boolVar bool
obj := TestData{
Field: &boolVar,
}
data1 := []byte(`{"field": true}`)
err := jsoniter.Unmarshal(data1, &obj)
should.NoError(err)
should.Equal(true, *(obj.Field.(*bool)))
data2 := []byte(`{"field": null}`)
err = jsoniter.Unmarshal(data2, &obj)
should.NoError(err)
should.Equal(nil, obj.Field)
// Checking stdlib behavior matches.
obj2 := TestData{
Field: &boolVar,
}
err = json.Unmarshal(data1, &obj2)
should.NoError(err)
should.Equal(true, *(obj2.Field.(*bool)))
err = json.Unmarshal(data2, &obj2)
should.NoError(err)
should.Equal(nil, obj2.Field)
}
func Test_overwrite_interface_ptr_value_with_nil(t *testing.T) {
type Wrapper struct {
Payload interface{} `json:"payload,omitempty"`
}
type Payload struct {
Value int `json:"val,omitempty"`
}
should := require.New(t)
payload := &Payload{}
wrapper := &Wrapper{
Payload: &payload,
}
err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal((*Payload)(nil), payload)
payload = &Payload{}
wrapper = &Wrapper{
Payload: &payload,
}
err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(&payload, wrapper.Payload)
should.Equal((*Payload)(nil), payload)
}
func Test_overwrite_interface_value_with_nil(t *testing.T) {
type Wrapper struct {
Payload interface{} `json:"payload,omitempty"`
}
type Payload struct {
Value int `json:"val,omitempty"`
}
should := require.New(t)
payload := &Payload{}
wrapper := &Wrapper{
Payload: payload,
}
err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(42, (*(wrapper.Payload.(*Payload))).Value)
err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(nil, wrapper.Payload)
should.Equal(42, payload.Value)
payload = &Payload{}
wrapper = &Wrapper{
Payload: payload,
}
err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Equal(nil, err)
should.Equal(42, (*(wrapper.Payload.(*Payload))).Value)
err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Equal(nil, err)
should.Equal(nil, wrapper.Payload)
should.Equal(42, payload.Value)
}
func Test_unmarshal_into_nil(t *testing.T) {
type Payload struct {
Value int `json:"val,omitempty"`
}
type Wrapper struct {
Payload interface{} `json:"payload,omitempty"`
}
should := require.New(t)
var payload *Payload
wrapper := &Wrapper{
Payload: payload,
}
err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Nil(err)
should.NotNil(wrapper.Payload)
should.Nil(payload)
err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Nil(err)
should.Nil(wrapper.Payload)
should.Nil(payload)
payload = nil
wrapper = &Wrapper{
Payload: payload,
}
err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
should.Nil(err)
should.NotNil(wrapper.Payload)
should.Nil(payload)
err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
should.Nil(err)
should.Nil(wrapper.Payload)
should.Nil(payload)
}

View File

@ -71,5 +71,19 @@ func init() {
Map map[string]string Map map[string]string
})(nil), })(nil),
(*[]uint8)(nil), (*[]uint8)(nil),
(*[]GeoLocation)(nil),
) )
} }
type GeoLocation struct {
Id string `json:"id,omitempty" db:"id"`
}
func (p *GeoLocation) MarshalJSON() ([]byte, error) {
return []byte(`{}`), nil
}
func (p *GeoLocation) UnmarshalJSON(input []byte) error {
p.Id = "hello"
return nil
}

View File

@ -59,6 +59,7 @@ func init() {
(*SameLevel2BothTagged)(nil), (*SameLevel2BothTagged)(nil),
(*SameLevel2NoTags)(nil), (*SameLevel2NoTags)(nil),
(*SameLevel2Tagged)(nil), (*SameLevel2Tagged)(nil),
(*EmbeddedPtr)(nil),
) )
} }
@ -218,3 +219,15 @@ type SameLevel2Tagged struct {
SameLevel2TaggedE1 SameLevel2TaggedE1
SameLevel2TaggedE2 SameLevel2TaggedE2
} }
type EmbeddedPtrO1 struct {
O1F string
}
type EmbeddedPtrOption struct {
O1 *EmbeddedPtrO1
}
type EmbeddedPtr struct {
EmbeddedPtrOption `json:","`
}

View File

@ -1,6 +1,7 @@
package test package test
func init() { func init() {
// TODO: fix this
//testCases = append(testCases, //testCases = append(testCases,
// (*struct { // (*struct {
// Upper bool `json:"M"` // Upper bool `json:"M"`

View File

@ -142,6 +142,9 @@ func init() {
B string `json:"b,omitempty"` B string `json:"b,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"` Annotations map[string]string `json:"annotations,omitempty"`
})(nil), })(nil),
(*struct {
Field bool `json:",omitempty,string"`
})(nil),
) )
} }

View File

@ -1,5 +1,7 @@
package test package test
import "time"
func init() { func init() {
testCases = append(testCases, testCases = append(testCases,
(*struct1Alias)(nil), (*struct1Alias)(nil),
@ -246,6 +248,13 @@ func init() {
(*struct { (*struct {
F struct3 F struct3
})(nil), })(nil),
(*struct {
TF1 struct {
F1 withTime
F2 *withTime
}
})(nil),
(*DeeplyNested)(nil),
) )
} }
@ -274,4 +283,28 @@ type struct3 struct {
F1 stringAlias F1 stringAlias
F2 stringAlias F2 stringAlias
F3 stringAlias F3 stringAlias
} }
type withTime struct {
time.Time
}
func (t *withTime) UnmarshalJSON(b []byte) error {
return nil
}
func (t withTime) MarshalJSON() ([]byte, error) {
return []byte(`"fake"`), nil
}
type YetYetAnotherObject struct {
Field string
}
type YetAnotherObject struct {
Field *YetYetAnotherObject
}
type AnotherObject struct {
Field *YetAnotherObject
}
type DeeplyNested struct {
Me *AnotherObject
}

View File

@ -18,53 +18,55 @@ var asymmetricTestCases [][2]interface{}
func Test_symmetric(t *testing.T) { func Test_symmetric(t *testing.T) {
for _, testCase := range testCases { for _, testCase := range testCases {
valType := reflect.TypeOf(testCase).Elem() valType := reflect.TypeOf(testCase).Elem()
fz := fuzz.New().MaxDepth(10).NilChance(0.3) t.Run(valType.String(), func(t *testing.T) {
for i := 0; i < 100; i++ { fz := fuzz.New().MaxDepth(10).NilChance(0.3)
beforePtrVal := reflect.New(valType) for i := 0; i < 100; i++ {
beforePtr := beforePtrVal.Interface() beforePtrVal := reflect.New(valType)
fz.Fuzz(beforePtr) beforePtr := beforePtrVal.Interface()
before := beforePtrVal.Elem().Interface() fz.Fuzz(beforePtr)
before := beforePtrVal.Elem().Interface()
jbStd, err := json.Marshal(before) jbStd, err := json.Marshal(before)
if err != nil { if err != nil {
t.Fatalf("failed to marshal with stdlib: %v", err) t.Fatalf("failed to marshal with stdlib: %v", err)
} }
if len(strings.TrimSpace(string(jbStd))) == 0 { if len(strings.TrimSpace(string(jbStd))) == 0 {
t.Fatal("stdlib marshal produced empty result and no error") t.Fatal("stdlib marshal produced empty result and no error")
} }
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
if err != nil { if err != nil {
t.Fatalf("failed to marshal with jsoniter: %v", err) t.Fatalf("failed to marshal with jsoniter: %v", err)
} }
if len(strings.TrimSpace(string(jbIter))) == 0 { if len(strings.TrimSpace(string(jbIter))) == 0 {
t.Fatal("jsoniter marshal produced empty result and no error") t.Fatal("jsoniter marshal produced empty result and no error")
} }
if string(jbStd) != string(jbIter) { if string(jbStd) != string(jbIter) {
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
indent(jbStd, " "), indent(jbIter, " "), dump(before)) indent(jbStd, " "), indent(jbIter, " "), dump(before))
} }
afterStdPtrVal := reflect.New(valType) afterStdPtrVal := reflect.New(valType)
afterStdPtr := afterStdPtrVal.Interface() afterStdPtr := afterStdPtrVal.Interface()
err = json.Unmarshal(jbIter, afterStdPtr) err = json.Unmarshal(jbIter, afterStdPtr)
if err != nil { if err != nil {
t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s", t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
err, indent(jbIter, " ")) err, indent(jbIter, " "))
}
afterIterPtrVal := reflect.New(valType)
afterIterPtr := afterIterPtrVal.Interface()
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, afterIterPtr)
if err != nil {
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
err, indent(jbIter, " "))
}
afterStd := afterStdPtrVal.Elem().Interface()
afterIter := afterIterPtrVal.Elem().Interface()
if fingerprint(afterStd) != fingerprint(afterIter) {
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
dump(afterStd), dump(afterIter), indent(jbIter, " "))
}
} }
afterIterPtrVal := reflect.New(valType) })
afterIterPtr := afterIterPtrVal.Interface()
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, afterIterPtr)
if err != nil {
t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
err, indent(jbIter, " "))
}
afterStd := afterStdPtrVal.Elem().Interface()
afterIter := afterIterPtrVal.Elem().Interface()
if fingerprint(afterStd) != fingerprint(afterIter) {
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
dump(afterStd), dump(afterIter), indent(jbIter, " "))
}
}
} }
} }

10
value_tests/array_test.go Normal file
View File

@ -0,0 +1,10 @@
package test
func init() {
two := float64(2)
marshalCases = append(marshalCases,
[1]*float64{nil},
[1]*float64{&two},
[2]*float64{},
)
}

10
value_tests/bool_test.go Normal file
View File

@ -0,0 +1,10 @@
package test
func init() {
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*struct {
Field bool `json:"field"`
})(nil),
input: `{"field": null}`,
})
}

View File

@ -1,33 +1,15 @@
// +build go1.8 package test
package jsoniter
import ( import (
"bytes"
"encoding/json"
"fmt" "fmt"
"strconv"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"strconv"
"bytes"
"github.com/json-iterator/go"
"encoding/json"
) )
func Test_read_big_float(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, `12.3`)
val := iter.ReadBigFloat()
val64, _ := val.Float64()
should.Equal(12.3, val64)
}
func Test_read_big_int(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, `92233720368547758079223372036854775807`)
val := iter.ReadBigInt()
should.NotNil(val)
should.Equal(`92233720368547758079223372036854775807`, val.String())
}
func Test_read_float(t *testing.T) { func Test_read_float(t *testing.T) {
inputs := []string{ inputs := []string{
`1.1`, `1000`, `9223372036854775807`, `12.3`, `-12.3`, `720368.54775807`, `720368.547758075`, `1.1`, `1000`, `9223372036854775807`, `12.3`, `-12.3`, `720368.54775807`, `720368.547758075`,
@ -37,14 +19,14 @@ func Test_read_float(t *testing.T) {
// non-streaming // non-streaming
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, input+",") iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
expected, err := strconv.ParseFloat(input, 32) expected, err := strconv.ParseFloat(input, 32)
should.Nil(err) should.Nil(err)
should.Equal(float32(expected), iter.ReadFloat32()) should.Equal(float32(expected), iter.ReadFloat32())
}) })
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, input+",") iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
expected, err := strconv.ParseFloat(input, 64) expected, err := strconv.ParseFloat(input, 64)
should.Nil(err) should.Nil(err)
should.Equal(expected, iter.ReadFloat64()) should.Equal(expected, iter.ReadFloat64())
@ -52,14 +34,14 @@ func Test_read_float(t *testing.T) {
// streaming // streaming
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := Parse(ConfigDefault, bytes.NewBufferString(input+","), 2) iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input+","), 2)
expected, err := strconv.ParseFloat(input, 32) expected, err := strconv.ParseFloat(input, 32)
should.Nil(err) should.Nil(err)
should.Equal(float32(expected), iter.ReadFloat32()) should.Equal(float32(expected), iter.ReadFloat32())
}) })
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := Parse(ConfigDefault, bytes.NewBufferString(input+","), 2) iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input+","), 2)
val := float64(0) val := float64(0)
err := json.Unmarshal([]byte(input), &val) err := json.Unmarshal([]byte(input), &val)
should.Nil(err) should.Nil(err)
@ -68,18 +50,6 @@ func Test_read_float(t *testing.T) {
} }
} }
func Test_read_float_as_interface(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, `12.3`)
should.Equal(float64(12.3), iter.Read())
}
func Test_wrap_float(t *testing.T) {
should := require.New(t)
str, err := MarshalToString(WrapFloat64(12.3))
should.Nil(err)
should.Equal("12.3", str)
}
func Test_write_float32(t *testing.T) { func Test_write_float32(t *testing.T) {
vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff, vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
@ -88,7 +58,7 @@ func Test_write_float32(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteFloat32Lossy(val) stream.WriteFloat32Lossy(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -99,7 +69,7 @@ func Test_write_float32(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -110,16 +80,16 @@ func Test_write_float32(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 10) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("abcdefg") stream.WriteRaw("abcdefg")
stream.WriteFloat32Lossy(1.123456) stream.WriteFloat32Lossy(1.123456)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
should.Equal("abcdefg1.123456", buf.String()) should.Equal("abcdefg1.123456", buf.String())
stream = NewStream(ConfigDefault, nil, 0) stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
stream.WriteFloat32(float32(0.0000001)) stream.WriteFloat32(float32(0.0000001))
should.Equal("1e-07", string(stream.buf)) should.Equal("1e-07", string(stream.Buffer()))
} }
func Test_write_float64(t *testing.T) { func Test_write_float64(t *testing.T) {
@ -129,7 +99,7 @@ func Test_write_float64(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteFloat64Lossy(val) stream.WriteFloat64Lossy(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -138,7 +108,7 @@ func Test_write_float64(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -147,71 +117,14 @@ func Test_write_float64(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 10) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("abcdefg") stream.WriteRaw("abcdefg")
stream.WriteFloat64Lossy(1.123456) stream.WriteFloat64Lossy(1.123456)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
should.Equal("abcdefg1.123456", buf.String()) should.Equal("abcdefg1.123456", buf.String())
stream = NewStream(ConfigDefault, nil, 0) stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
stream.WriteFloat64(float64(0.0000001)) stream.WriteFloat64(float64(0.0000001))
should.Equal("1e-07", string(stream.buf)) should.Equal("1e-07", string(stream.Buffer()))
} }
func Test_read_float64_cursor(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, "[1.23456789\n,2,3]")
should.True(iter.ReadArray())
should.Equal(1.23456789, iter.Read())
should.True(iter.ReadArray())
should.Equal(float64(2), iter.Read())
}
func Test_read_float_scientific(t *testing.T) {
should := require.New(t)
var obj interface{}
should.Nil(UnmarshalFromString(`1e1`, &obj))
should.Equal(float64(10), obj)
should.Nil(json.Unmarshal([]byte(`1e1`), &obj))
should.Equal(float64(10), obj)
should.Nil(UnmarshalFromString(`1.0e1`, &obj))
should.Equal(float64(10), obj)
should.Nil(json.Unmarshal([]byte(`1.0e1`), &obj))
should.Equal(float64(10), obj)
}
func Test_lossy_float_marshal(t *testing.T) {
should := require.New(t)
api := Config{MarshalFloatWith6Digits: true}.Froze()
output, err := api.MarshalToString(float64(0.1234567))
should.Nil(err)
should.Equal("0.123457", output)
output, err = api.MarshalToString(float32(0.1234567))
should.Nil(err)
should.Equal("0.123457", output)
}
func Test_read_number(t *testing.T) {
should := require.New(t)
iter := ParseString(ConfigDefault, `92233720368547758079223372036854775807`)
val := iter.ReadNumber()
should.Equal(`92233720368547758079223372036854775807`, string(val))
}
func Benchmark_jsoniter_float(b *testing.B) {
b.ReportAllocs()
input := []byte(`1.1123,`)
iter := NewIterator(ConfigDefault)
for n := 0; n < b.N; n++ {
iter.ResetBytes(input)
iter.ReadFloat64()
}
}
func Benchmark_json_float(b *testing.B) {
for n := 0; n < b.N; n++ {
result := float64(0)
json.Unmarshal([]byte(`1.1`), &result)
}
}

View File

@ -1,69 +1,55 @@
// +build go1.8 package test
package jsoniter
import ( import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"strconv"
"testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"strconv"
"fmt"
"testing"
"bytes"
"github.com/json-iterator/go"
) )
func Test_read_uint64_invalid(t *testing.T) { func init() {
should := require.New(t) unmarshalCases = append(unmarshalCases, unmarshalCase{
iter := ParseString(ConfigDefault, ",") ptr: (*struct {
iter.ReadUint64() F1 int8
should.NotNil(iter.Error) F2 int16
F3 int32
F4 int64
F5 int
F6 uint8
F7 uint16
F8 uint32
F9 uint64
F10 uint
F11 float32
F12 float64
F13 uintptr
})(nil),
input: `{
"f1":null,
"f2":null,
"f3":null,
"f4":null,
"f5":null,
"f6":null,
"f7":null,
"f8":null,
"f9":null,
"f10":null,
"f11":null,
"f12":null,
"f13":null
}`,
})
} }
func Test_read_int_from_null(t *testing.T) { func Test_int8(t *testing.T) {
type TestObject struct {
F1 int8
F2 int16
F3 int32
F4 int64
F5 int
F6 uint8
F7 uint16
F8 uint32
F9 uint64
F10 uint
F11 float32
F12 float64
F13 uintptr
}
should := require.New(t)
obj := TestObject{}
err := Unmarshal([]byte(`{
"f1":null,
"f2":null,
"f3":null,
"f4":null,
"f5":null,
"f6":null,
"f7":null,
"f8":null,
"f9":null,
"f10":null,
"f11":null,
"f12":null,
"f13":null
}`), &obj)
should.Nil(err)
}
func _int8(t *testing.T) {
inputs := []string{`127`, `-128`} inputs := []string{`127`, `-128`}
for _, input := range inputs { for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, input) iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 8) expected, err := strconv.ParseInt(input, 10, 8)
should.Nil(err) should.Nil(err)
should.Equal(int8(expected), iter.ReadInt8()) should.Equal(int8(expected), iter.ReadInt8())
@ -76,7 +62,7 @@ func Test_read_int16(t *testing.T) {
for _, input := range inputs { for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, input) iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 16) expected, err := strconv.ParseInt(input, 10, 16)
should.Nil(err) should.Nil(err)
should.Equal(int16(expected), iter.ReadInt16()) should.Equal(int16(expected), iter.ReadInt16())
@ -89,14 +75,14 @@ func Test_read_int32(t *testing.T) {
for _, input := range inputs { for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, input) iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 32) expected, err := strconv.ParseInt(input, 10, 32)
should.Nil(err) should.Nil(err)
should.Equal(int32(expected), iter.ReadInt32()) should.Equal(int32(expected), iter.ReadInt32())
}) })
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2) iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input), 2)
expected, err := strconv.ParseInt(input, 10, 32) expected, err := strconv.ParseInt(input, 10, 32)
should.Nil(err) should.Nil(err)
should.Equal(int32(expected), iter.ReadInt32()) should.Equal(int32(expected), iter.ReadInt32())
@ -104,31 +90,15 @@ func Test_read_int32(t *testing.T) {
} }
} }
func Test_read_int32_array(t *testing.T) {
should := require.New(t)
input := `[123,456,789]`
val := make([]int32, 0)
UnmarshalFromString(input, &val)
should.Equal(3, len(val))
}
func Test_read_int64_array(t *testing.T) {
should := require.New(t)
input := `[123,456,789]`
val := make([]int64, 0)
UnmarshalFromString(input, &val)
should.Equal(3, len(val))
}
func Test_read_int_overflow(t *testing.T) { func Test_read_int_overflow(t *testing.T) {
should := require.New(t) should := require.New(t)
inputArr := []string{"123451", "-123451"} inputArr := []string{"123451", "-123451"}
for _, s := range inputArr { for _, s := range inputArr {
iter := ParseString(ConfigDefault, s) iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt8() iter.ReadInt8()
should.NotNil(iter.Error) should.NotNil(iter.Error)
iterU := ParseString(ConfigDefault, s) iterU := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterU.ReadUint8() iterU.ReadUint8()
should.NotNil(iterU.Error) should.NotNil(iterU.Error)
@ -136,33 +106,33 @@ func Test_read_int_overflow(t *testing.T) {
inputArr = []string{"12345678912", "-12345678912"} inputArr = []string{"12345678912", "-12345678912"}
for _, s := range inputArr { for _, s := range inputArr {
iter := ParseString(ConfigDefault, s) iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt16() iter.ReadInt16()
should.NotNil(iter.Error) should.NotNil(iter.Error)
iterUint := ParseString(ConfigDefault, s) iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterUint.ReadUint16() iterUint.ReadUint16()
should.NotNil(iterUint.Error) should.NotNil(iterUint.Error)
} }
inputArr = []string{"3111111111", "-3111111111", "1234232323232323235678912", "-1234567892323232323212"} inputArr = []string{"3111111111", "-3111111111", "1234232323232323235678912", "-1234567892323232323212"}
for _, s := range inputArr { for _, s := range inputArr {
iter := ParseString(ConfigDefault, s) iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt32() iter.ReadInt32()
should.NotNil(iter.Error) should.NotNil(iter.Error)
iterUint := ParseString(ConfigDefault, s) iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterUint.ReadUint32() iterUint.ReadUint32()
should.NotNil(iterUint.Error) should.NotNil(iterUint.Error)
} }
inputArr = []string{"9223372036854775811", "-9523372036854775807", "1234232323232323235678912", "-1234567892323232323212"} inputArr = []string{"9223372036854775811", "-9523372036854775807", "1234232323232323235678912", "-1234567892323232323212"}
for _, s := range inputArr { for _, s := range inputArr {
iter := ParseString(ConfigDefault, s) iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt64() iter.ReadInt64()
should.NotNil(iter.Error) should.NotNil(iter.Error)
iterUint := ParseString(ConfigDefault, s) iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterUint.ReadUint64() iterUint.ReadUint64()
should.NotNil(iterUint.Error) should.NotNil(iterUint.Error)
} }
@ -173,14 +143,14 @@ func Test_read_int64(t *testing.T) {
for _, input := range inputs { for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := ParseString(ConfigDefault, input) iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 64) expected, err := strconv.ParseInt(input, 10, 64)
should.Nil(err) should.Nil(err)
should.Equal(expected, iter.ReadInt64()) should.Equal(expected, iter.ReadInt64())
}) })
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) { t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t) should := require.New(t)
iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2) iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input), 2)
expected, err := strconv.ParseInt(input, 10, 64) expected, err := strconv.ParseInt(input, 10, 64)
should.Nil(err) should.Nil(err)
should.Equal(expected, iter.ReadInt64()) should.Equal(expected, iter.ReadInt64())
@ -188,20 +158,6 @@ func Test_read_int64(t *testing.T) {
} }
} }
func Test_read_int64_overflow(t *testing.T) {
should := require.New(t)
input := "123456789123456789123456789123456789,"
iter := ParseString(ConfigDefault, input)
iter.ReadInt64()
should.NotNil(iter.Error)
}
func Test_wrap_int(t *testing.T) {
should := require.New(t)
str, err := MarshalToString(WrapInt64(100))
should.Nil(err)
should.Equal("100", str)
}
func Test_write_uint8(t *testing.T) { func Test_write_uint8(t *testing.T) {
vals := []uint8{0, 1, 11, 111, 255} vals := []uint8{0, 1, 11, 111, 255}
@ -209,7 +165,7 @@ func Test_write_uint8(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint8(val) stream.WriteUint8(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -218,7 +174,7 @@ func Test_write_uint8(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -227,7 +183,7 @@ func Test_write_uint8(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 3) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 3)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteUint8(100) // should clear buffer stream.WriteUint8(100) // should clear buffer
stream.Flush() stream.Flush()
@ -241,7 +197,7 @@ func Test_write_int8(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt8(val) stream.WriteInt8(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -250,7 +206,7 @@ func Test_write_int8(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -259,7 +215,7 @@ func Test_write_int8(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteInt8(-100) // should clear buffer stream.WriteInt8(-100) // should clear buffer
stream.Flush() stream.Flush()
@ -273,7 +229,7 @@ func Test_write_uint16(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint16(val) stream.WriteUint16(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -282,7 +238,7 @@ func Test_write_uint16(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -291,7 +247,7 @@ func Test_write_uint16(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 5) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 5)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteUint16(10000) // should clear buffer stream.WriteUint16(10000) // should clear buffer
stream.Flush() stream.Flush()
@ -305,7 +261,7 @@ func Test_write_int16(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt16(val) stream.WriteInt16(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -314,7 +270,7 @@ func Test_write_int16(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -323,7 +279,7 @@ func Test_write_int16(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 6) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 6)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteInt16(-10000) // should clear buffer stream.WriteInt16(-10000) // should clear buffer
stream.Flush() stream.Flush()
@ -337,7 +293,7 @@ func Test_write_uint32(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint32(val) stream.WriteUint32(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -346,7 +302,7 @@ func Test_write_uint32(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -355,7 +311,7 @@ func Test_write_uint32(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 10) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteUint32(0xffffffff) // should clear buffer stream.WriteUint32(0xffffffff) // should clear buffer
stream.Flush() stream.Flush()
@ -369,7 +325,7 @@ func Test_write_int32(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt32(val) stream.WriteInt32(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -378,7 +334,7 @@ func Test_write_int32(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -387,7 +343,7 @@ func Test_write_int32(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 11) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 11)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteInt32(-0x7fffffff) // should clear buffer stream.WriteInt32(-0x7fffffff) // should clear buffer
stream.Flush() stream.Flush()
@ -403,7 +359,7 @@ func Test_write_uint64(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint64(val) stream.WriteUint64(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -412,7 +368,7 @@ func Test_write_uint64(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -421,7 +377,7 @@ func Test_write_uint64(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 10) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteUint64(0xffffffff) // should clear buffer stream.WriteUint64(0xffffffff) // should clear buffer
stream.Flush() stream.Flush()
@ -437,7 +393,7 @@ func Test_write_int64(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt64(val) stream.WriteInt64(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -446,7 +402,7 @@ func Test_write_int64(t *testing.T) {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) { t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val) stream.WriteVal(val)
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
@ -455,119 +411,10 @@ func Test_write_int64(t *testing.T) {
} }
should := require.New(t) should := require.New(t)
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 10) stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("a") stream.WriteRaw("a")
stream.WriteInt64(0xffffffff) // should clear buffer stream.WriteInt64(0xffffffff) // should clear buffer
stream.Flush() stream.Flush()
should.Nil(stream.Error) should.Nil(stream.Error)
should.Equal("a4294967295", buf.String()) should.Equal("a4294967295", buf.String())
} }
func Test_write_val_int(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096)
stream.WriteVal(1001)
stream.Flush()
should.Nil(stream.Error)
should.Equal("1001", buf.String())
}
func Test_write_val_int_ptr(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := NewStream(ConfigDefault, buf, 4096)
val := 1001
stream.WriteVal(&val)
stream.Flush()
should.Nil(stream.Error)
should.Equal("1001", buf.String())
}
func Test_json_number(t *testing.T) {
should := require.New(t)
var arr []json.Number
err := Unmarshal([]byte(`[1]`), &arr)
should.Nil(err)
should.Equal(json.Number("1"), arr[0])
str, err := MarshalToString(arr)
should.Nil(err)
should.Equal(`[1]`, str)
}
func Test_jsoniter_number(t *testing.T) {
should := require.New(t)
var arr []Number
err := Unmarshal([]byte(`[1]`), &arr)
should.Nil(err)
should.Equal(Number("1"), arr[0])
str, isNumber := CastJsonNumber(arr[0])
should.True(isNumber)
should.Equal("1", str)
}
func Test_non_numeric_as_number(t *testing.T) {
should := require.New(t)
var v1 json.Number
err := Unmarshal([]byte(`"500"`), &v1)
should.Nil(err)
should.Equal("500", string(v1))
var v2 Number
err = Unmarshal([]byte(`"500"`), &v2)
should.Nil(err)
should.Equal("500", string(v2))
}
func Test_null_as_number(t *testing.T) {
should := require.New(t)
var v1 json.Number
err := json.Unmarshal([]byte(`null`), &v1)
should.Nil(err)
should.Equal("", string(v1))
output, err := json.Marshal(v1)
should.NoError(err)
should.Equal("0", string(output))
var v2 Number
err = Unmarshal([]byte(`null`), &v2)
should.Nil(err)
should.Equal("", string(v2))
output, err = Marshal(v2)
should.NoError(err)
should.Equal("0", string(output))
}
func Test_float_as_int(t *testing.T) {
should := require.New(t)
var i int
should.NotNil(Unmarshal([]byte(`1.1`), &i))
}
func Benchmark_jsoniter_encode_int(b *testing.B) {
stream := NewStream(ConfigDefault, ioutil.Discard, 64)
for n := 0; n < b.N; n++ {
stream.n = 0
stream.WriteUint64(0xffffffff)
}
}
func Benchmark_itoa(b *testing.B) {
for n := 0; n < b.N; n++ {
strconv.FormatInt(0xffffffff, 10)
}
}
func Benchmark_jsoniter_int(b *testing.B) {
iter := NewIterator(ConfigDefault)
input := []byte(`100`)
for n := 0; n < b.N; n++ {
iter.ResetBytes(input)
iter.ReadInt64()
}
}
func Benchmark_json_int(b *testing.B) {
for n := 0; n < b.N; n++ {
result := int64(0)
json.Unmarshal([]byte(`-100`), &result)
}
}

18
value_tests/map_test.go Normal file
View File

@ -0,0 +1,18 @@
package test
func init() {
marshalCases = append(marshalCases,
map[string]interface{}{"abc": 1},
map[string]MyInterface{"hello": MyString("world")},
)
}
type MyInterface interface {
Hello() string
}
type MyString string
func (ms MyString) Hello() string {
return string(ms)
}

View File

@ -0,0 +1,19 @@
package test
func init() {
marshalCases = append(marshalCases,
//withChan{}, TODO: fix this
)
}
type withChan struct {
F2 chan []byte
}
func (q withChan) MarshalJSON() ([]byte, error) {
return []byte(`""`), nil
}
func (q *withChan) UnmarshalJSON(value []byte) error {
return nil
}

View File

@ -0,0 +1,17 @@
package test
import "encoding/json"
func init() {
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*json.Number)(nil),
input: `"500"`,
}, unmarshalCase{
ptr: (*json.Number)(nil),
input: `1`,
}, unmarshalCase{
ptr: (*json.Number)(nil),
input: `null`,
})
marshalCases = append(marshalCases, json.Number(""))
}

20
value_tests/ptr_test.go Normal file
View File

@ -0,0 +1,20 @@
package test
func init() {
var pEFace = func(val interface{}) *interface{} {
return &val
}
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (**interface{})(nil),
input: `"hello"`,
}, unmarshalCase{
ptr: (**interface{})(nil),
input: `1e1`,
}, unmarshalCase{
ptr: (**interface{})(nil),
input: `1.0e1`,
})
marshalCases = append(marshalCases,
pEFace("hello"),
)
}

View File

@ -0,0 +1,9 @@
package test
import "encoding/json"
func init() {
marshalCases = append(marshalCases,
json.RawMessage("{}"),
)
}

View File

@ -0,0 +1,5 @@
package test
func init() {
marshalCases = append(marshalCases, []interface{}{"hello"})
}

View File

@ -0,0 +1,82 @@
package test
import (
"time"
"encoding/json"
)
func init() {
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*struct {
Field interface{}
})(nil),
input: `{"Field": "hello"}`,
})
marshalCases = append(marshalCases,
struct {
Field map[string]interface{}
}{
map[string]interface{}{"hello": "world"},
},
struct {
Field map[string]interface{}
Field2 string
}{
map[string]interface{}{"hello": "world"}, "",
},
struct {
Field interface{}
}{
1024,
},
struct {
Field MyInterface
}{
MyString("hello"),
},
struct {
F *float64
}{},
// TODO: fix this
//struct {
// *time.Time
//}{},
struct {
*time.Time
}{&time.Time{}},
struct {
*StructVarious
}{&StructVarious{}},
struct {
*StructVarious
}{},
struct {
Field1 int
Field2 [1]*float64
}{},
struct {
Field interface{} `json:"field,omitempty"`
}{},
struct {
Field MyInterface `json:"field,omitempty"`
}{},
struct {
Field MyInterface `json:"field,omitempty"`
}{MyString("hello")},
struct {
Field json.Marshaler `json:"field"`
}{},
struct {
Field MyInterface `json:"field"`
}{},
struct {
Field MyInterface `json:"field"`
}{MyString("hello")},
)
}
type StructVarious struct {
Field0 string
Field1 []string
Field2 map[string]interface{}
}

43
value_tests/value_test.go Normal file
View File

@ -0,0 +1,43 @@
package test
import (
"testing"
"reflect"
"encoding/json"
"github.com/stretchr/testify/require"
"github.com/json-iterator/go"
)
type unmarshalCase struct {
ptr interface{}
input string
}
var unmarshalCases []unmarshalCase
var marshalCases []interface{}
func Test_unmarshal(t *testing.T) {
should := require.New(t)
for _, testCase := range unmarshalCases {
valType := reflect.TypeOf(testCase.ptr).Elem()
ptr1Val := reflect.New(valType)
err1 := json.Unmarshal([]byte(testCase.input), ptr1Val.Interface())
should.NoError(err1)
ptr2Val := reflect.New(valType)
err2 := jsoniter.Unmarshal([]byte(testCase.input), ptr2Val.Interface())
should.NoError(err2)
should.Equal(ptr1Val.Interface(), ptr2Val.Interface())
}
}
func Test_marshal(t *testing.T) {
should := require.New(t)
for _, testCase := range marshalCases {
output1, err1 := json.Marshal(testCase)
should.NoError(err1)
output2, err2 := jsoniter.Marshal(testCase)
should.NoError(err2)
should.Equal(string(output1), string(output2))
}
}