added vendors

This commit is contained in:
mickymiek
2018-12-19 15:29:25 +01:00
parent 12e6881669
commit 8ee6bc4b91
2952 changed files with 1124359 additions and 1 deletions

View File

@ -0,0 +1,20 @@
package test
func init() {
two := float64(2)
marshalCases = append(marshalCases,
[1]*float64{nil},
[1]*float64{&two},
[2]*float64{},
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*[0]int)(nil),
input: `[1]`,
}, unmarshalCase{
ptr: (*[1]int)(nil),
input: `[2]`,
}, unmarshalCase{
ptr: (*[1]int)(nil),
input: `[]`,
})
}

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

@ -0,0 +1,78 @@
package test
func init() {
var pEFace = func(val interface{}) *interface{} {
return &val
}
var pInt = func(val int) *int {
return &val
}
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (**interface{})(nil),
input: `"hello"`,
}, unmarshalCase{
ptr: (**interface{})(nil),
input: `1e1`,
}, unmarshalCase{
ptr: (**interface{})(nil),
input: `1.0e1`,
}, unmarshalCase{
ptr: (*[]interface{})(nil),
input: `[1.0e1]`,
}, unmarshalCase{
ptr: (*struct {
Field interface{}
})(nil),
input: `{"field":"hello"}`,
}, unmarshalCase{
obj: func() interface{} {
type TestData struct {
Name string `json:"name"`
}
o := &TestData{}
return &o
},
input: `{"name":"value"}`,
}, unmarshalCase{
obj: func() interface{} {
b := true
return &struct {
Field interface{} `json:"field"`
}{&b}
},
input: `{"field": null}`,
}, unmarshalCase{
obj: func() interface{} {
var pb *bool
return &struct {
Field interface{} `json:"field"`
}{&pb}
},
input: `{"field": null}`,
}, unmarshalCase{
obj: func() interface{} {
b := true
pb := &b
return &struct {
Field interface{} `json:"field"`
}{&pb}
},
input: `{"field": null}`,
})
marshalCases = append(marshalCases,
pEFace("hello"),
struct {
Field interface{}
}{"hello"},
struct {
Field interface{}
}{struct {
field chan int
}{}},
struct {
Field interface{}
}{struct {
Field *int
}{pInt(100)}},
)
}

View File

@ -0,0 +1,36 @@
package test
import (
"github.com/json-iterator/go"
"github.com/stretchr/testify/require"
"reflect"
"testing"
)
func Test_errorInput(t *testing.T) {
for _, testCase := range unmarshalCases {
if testCase.obj != nil {
continue
}
valType := reflect.TypeOf(testCase.ptr).Elem()
t.Run(valType.String(), func(t *testing.T) {
for _, data := range []string{
`x`,
`n`,
`nul`,
`{x}`,
`{"x"}`,
`{"x": "y"x}`,
`{"x": "y"`,
`{"x": "y", "a"}`,
`[`,
`[{"x": "y"}`,
} {
ptrVal := reflect.New(valType)
ptr := ptrVal.Interface()
err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(data), ptr)
require.Error(t, err, "on input %q", data)
}
})
}
}

View File

@ -0,0 +1,129 @@
package test
import (
"bytes"
"encoding/json"
"fmt"
"github.com/json-iterator/go"
"github.com/stretchr/testify/require"
"strconv"
"testing"
)
func Test_read_float(t *testing.T) {
inputs := []string{
`1.1`, `1000`, `9223372036854775807`, `12.3`, `-12.3`, `720368.54775807`, `720368.547758075`,
`1e1`, `1e+1`, `1e-1`, `1E1`, `1E+1`, `1E-1`, `-1e1`, `-1e+1`, `-1e-1`,
}
for _, input := range inputs {
// non-streaming
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
expected, err := strconv.ParseFloat(input, 32)
should.Nil(err)
should.Equal(float32(expected), iter.ReadFloat32())
})
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
expected, err := strconv.ParseFloat(input, 64)
should.Nil(err)
should.Equal(expected, iter.ReadFloat64())
})
// streaming
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input+","), 2)
expected, err := strconv.ParseFloat(input, 32)
should.Nil(err)
should.Equal(float32(expected), iter.ReadFloat32())
})
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input+","), 2)
val := float64(0)
err := json.Unmarshal([]byte(input), &val)
should.Nil(err)
should.Equal(val, iter.ReadFloat64())
})
}
}
func Test_write_float32(t *testing.T) {
vals := []float32{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteFloat32Lossy(val)
stream.Flush()
should.Nil(stream.Error)
output, err := json.Marshal(val)
should.Nil(err)
should.Equal(string(output), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
output, err := json.Marshal(val)
should.Nil(err)
should.Equal(string(output), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("abcdefg")
stream.WriteFloat32Lossy(1.123456)
stream.Flush()
should.Nil(stream.Error)
should.Equal("abcdefg1.123456", buf.String())
stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
stream.WriteFloat32(float32(0.0000001))
should.Equal("1e-07", string(stream.Buffer()))
}
func Test_write_float64(t *testing.T) {
vals := []float64{0, 1, -1, 99, 0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0x4ffffff, 0xfffffff,
-0x4ffffff, -0xfffffff, 1.2345, 1.23456, 1.234567, 1.001}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteFloat64Lossy(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatFloat(val, 'f', -1, 64), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatFloat(val, 'f', -1, 64), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("abcdefg")
stream.WriteFloat64Lossy(1.123456)
stream.Flush()
should.Nil(stream.Error)
should.Equal("abcdefg1.123456", buf.String())
stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
stream.WriteFloat64(float64(0.0000001))
should.Equal("1e-07", string(stream.Buffer()))
}

View File

@ -0,0 +1,45 @@
package test
import "io"
func init() {
var pCloser1 = func(str string) *io.Closer {
closer := io.Closer(strCloser1(str))
return &closer
}
var pCloser2 = func(str string) *io.Closer {
strCloser := strCloser2(str)
closer := io.Closer(&strCloser)
return &closer
}
marshalCases = append(marshalCases,
pCloser1("hello"),
pCloser2("hello"),
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*[]io.Closer)(nil),
input: "[null]",
}, unmarshalCase{
obj: func() interface{} {
strCloser := strCloser2("")
return &struct {
Field io.Closer
}{
&strCloser,
}
},
input: `{"Field": "hello"}`,
})
}
type strCloser1 string
func (closer strCloser1) Close() error {
return nil
}
type strCloser2 string
func (closer *strCloser2) Close() error {
return nil
}

View File

@ -0,0 +1,419 @@
package test
import (
"bytes"
"fmt"
"github.com/json-iterator/go"
"github.com/stretchr/testify/require"
"strconv"
"testing"
)
func init() {
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*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
})(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_int8(t *testing.T) {
inputs := []string{`127`, `-128`}
for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 8)
should.Nil(err)
should.Equal(int8(expected), iter.ReadInt8())
})
}
}
func Test_read_int16(t *testing.T) {
inputs := []string{`32767`, `-32768`}
for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 16)
should.Nil(err)
should.Equal(int16(expected), iter.ReadInt16())
})
}
}
func Test_read_int32(t *testing.T) {
inputs := []string{`1`, `12`, `123`, `1234`, `12345`, `123456`, `2147483647`, `-2147483648`}
for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 32)
should.Nil(err)
should.Equal(int32(expected), iter.ReadInt32())
})
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input), 2)
expected, err := strconv.ParseInt(input, 10, 32)
should.Nil(err)
should.Equal(int32(expected), iter.ReadInt32())
})
}
}
func Test_read_int_overflow(t *testing.T) {
should := require.New(t)
inputArr := []string{"123451", "-123451"}
for _, s := range inputArr {
iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt8()
should.NotNil(iter.Error)
iterU := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterU.ReadUint8()
should.NotNil(iterU.Error)
}
inputArr = []string{"12345678912", "-12345678912"}
for _, s := range inputArr {
iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt16()
should.NotNil(iter.Error)
iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterUint.ReadUint16()
should.NotNil(iterUint.Error)
}
inputArr = []string{"3111111111", "-3111111111", "1234232323232323235678912", "-1234567892323232323212"}
for _, s := range inputArr {
iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt32()
should.NotNil(iter.Error)
iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterUint.ReadUint32()
should.NotNil(iterUint.Error)
}
inputArr = []string{"9223372036854775811", "-9523372036854775807", "1234232323232323235678912", "-1234567892323232323212"}
for _, s := range inputArr {
iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iter.ReadInt64()
should.NotNil(iter.Error)
iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
iterUint.ReadUint64()
should.NotNil(iterUint.Error)
}
}
func Test_read_int64(t *testing.T) {
inputs := []string{`1`, `12`, `123`, `1234`, `12345`, `123456`, `9223372036854775807`, `-9223372036854775808`}
for _, input := range inputs {
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
expected, err := strconv.ParseInt(input, 10, 64)
should.Nil(err)
should.Equal(expected, iter.ReadInt64())
})
t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
should := require.New(t)
iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input), 2)
expected, err := strconv.ParseInt(input, 10, 64)
should.Nil(err)
should.Equal(expected, iter.ReadInt64())
})
}
}
func Test_write_uint8(t *testing.T) {
vals := []uint8{0, 1, 11, 111, 255}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint8(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 3)
stream.WriteRaw("a")
stream.WriteUint8(100) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a100", buf.String())
}
func Test_write_int8(t *testing.T) {
vals := []int8{0, 1, -1, 99, 0x7f, -0x80}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt8(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4)
stream.WriteRaw("a")
stream.WriteInt8(-100) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a-100", buf.String())
}
func Test_write_uint16(t *testing.T) {
vals := []uint16{0, 1, 11, 111, 255, 0xfff, 0xffff}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint16(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 5)
stream.WriteRaw("a")
stream.WriteUint16(10000) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a10000", buf.String())
}
func Test_write_int16(t *testing.T) {
vals := []int16{0, 1, 11, 111, 255, 0xfff, 0x7fff, -0x8000}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt16(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 6)
stream.WriteRaw("a")
stream.WriteInt16(-10000) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a-10000", buf.String())
}
func Test_write_uint32(t *testing.T) {
vals := []uint32{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint32(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("a")
stream.WriteUint32(0xffffffff) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a4294967295", buf.String())
}
func Test_write_int32(t *testing.T) {
vals := []int32{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0x7fffffff, -0x80000000}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt32(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(int64(val), 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 11)
stream.WriteRaw("a")
stream.WriteInt32(-0x7fffffff) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a-2147483647", buf.String())
}
func Test_write_uint64(t *testing.T) {
vals := []uint64{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff,
0xfffffffff, 0xffffffffff, 0xfffffffffff, 0xffffffffffff, 0xfffffffffffff, 0xffffffffffffff,
0xfffffffffffffff, 0xffffffffffffffff}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteUint64(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatUint(uint64(val), 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("a")
stream.WriteUint64(0xffffffff) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a4294967295", buf.String())
}
func Test_write_int64(t *testing.T) {
vals := []int64{0, 1, 11, 111, 255, 999999, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff,
0xfffffffff, 0xffffffffff, 0xfffffffffff, 0xffffffffffff, 0xfffffffffffff, 0xffffffffffffff,
0xfffffffffffffff, 0x7fffffffffffffff, -0x8000000000000000}
for _, val := range vals {
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteInt64(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(val, 10), buf.String())
})
t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
stream.WriteVal(val)
stream.Flush()
should.Nil(stream.Error)
should.Equal(strconv.FormatInt(val, 10), buf.String())
})
}
should := require.New(t)
buf := &bytes.Buffer{}
stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
stream.WriteRaw("a")
stream.WriteInt64(0xffffffff) // should clear buffer
stream.Flush()
should.Nil(stream.Error)
should.Equal("a4294967295", buf.String())
}

View File

@ -0,0 +1,226 @@
package test
import (
"bytes"
"encoding/json"
"github.com/json-iterator/go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io"
"testing"
)
func Test_missing_object_end(t *testing.T) {
should := require.New(t)
type TestObject struct {
Metric string `json:"metric"`
Tags map[string]interface{} `json:"tags"`
}
obj := TestObject{}
should.NotNil(jsoniter.UnmarshalFromString(`{"metric": "sys.777","tags": {"a":"123"}`, &obj))
}
func Test_missing_array_end(t *testing.T) {
should := require.New(t)
should.NotNil(jsoniter.UnmarshalFromString(`[1,2,3`, &[]int{}))
}
func Test_invalid_any(t *testing.T) {
should := require.New(t)
any := jsoniter.Get([]byte("[]"))
should.Equal(jsoniter.InvalidValue, any.Get(0.3).ValueType())
// is nil correct ?
should.Equal(nil, any.Get(0.3).GetInterface())
any = any.Get(0.3)
should.Equal(false, any.ToBool())
should.Equal(int(0), any.ToInt())
should.Equal(int32(0), any.ToInt32())
should.Equal(int64(0), any.ToInt64())
should.Equal(uint(0), any.ToUint())
should.Equal(uint32(0), any.ToUint32())
should.Equal(uint64(0), any.ToUint64())
should.Equal(float32(0), any.ToFloat32())
should.Equal(float64(0), any.ToFloat64())
should.Equal("", any.ToString())
should.Equal(jsoniter.InvalidValue, any.Get(0.1).Get(1).ValueType())
}
func Test_invalid_struct_input(t *testing.T) {
should := require.New(t)
type TestObject struct{}
input := []byte{54, 141, 30}
obj := TestObject{}
should.NotNil(jsoniter.Unmarshal(input, &obj))
}
func Test_invalid_slice_input(t *testing.T) {
should := require.New(t)
type TestObject struct{}
input := []byte{93}
obj := []string{}
should.NotNil(jsoniter.Unmarshal(input, &obj))
}
func Test_invalid_array_input(t *testing.T) {
should := require.New(t)
type TestObject struct{}
input := []byte{93}
obj := [0]string{}
should.NotNil(jsoniter.Unmarshal(input, &obj))
}
func Test_invalid_float(t *testing.T) {
inputs := []string{
`1.e1`, // dot without following digit
`1.`, // dot can not be the last char
``, // empty number
`01`, // extra leading zero
`-`, // negative without digit
`--`, // double negative
`--2`, // double negative
}
for _, input := range inputs {
t.Run(input, func(t *testing.T) {
should := require.New(t)
iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
iter.Skip()
should.NotEqual(io.EOF, iter.Error)
should.NotNil(iter.Error)
v := float64(0)
should.NotNil(json.Unmarshal([]byte(input), &v))
iter = jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
iter.ReadFloat64()
should.NotEqual(io.EOF, iter.Error)
should.NotNil(iter.Error)
iter = jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
iter.ReadFloat32()
should.NotEqual(io.EOF, iter.Error)
should.NotNil(iter.Error)
})
}
}
func Test_chan(t *testing.T) {
t.Skip("do not support chan")
type TestObject struct {
MyChan chan bool
MyField int
}
should := require.New(t)
obj := TestObject{}
str, err := json.Marshal(obj)
should.Nil(err)
should.Equal(``, str)
}
func Test_invalid_number(t *testing.T) {
type Message struct {
Number int `json:"number"`
}
obj := Message{}
decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(bytes.NewBufferString(`{"number":"5"}`))
err := decoder.Decode(&obj)
invalidStr := err.Error()
result, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(invalidStr)
should := require.New(t)
should.Nil(err)
result2, err := json.Marshal(invalidStr)
should.Nil(err)
should.Equal(string(result2), string(result))
}
func Test_valid(t *testing.T) {
should := require.New(t)
should.True(jsoniter.Valid([]byte(`{}`)))
should.False(jsoniter.Valid([]byte(`{`)))
}
func Test_nil_pointer(t *testing.T) {
should := require.New(t)
data := []byte(`{"A":0}`)
type T struct {
X int
}
var obj *T
err := jsoniter.Unmarshal(data, obj)
should.NotNil(err)
}
func Test_func_pointer_type(t *testing.T) {
type TestObject2 struct {
F func()
}
type TestObject1 struct {
Obj *TestObject2
}
t.Run("encode null is valid", func(t *testing.T) {
should := require.New(t)
output, err := json.Marshal(TestObject1{})
should.Nil(err)
should.Equal(`{"Obj":null}`, string(output))
output, err = jsoniter.Marshal(TestObject1{})
should.Nil(err)
should.Equal(`{"Obj":null}`, string(output))
})
t.Run("encode not null is invalid", func(t *testing.T) {
should := require.New(t)
_, err := json.Marshal(TestObject1{Obj: &TestObject2{}})
should.NotNil(err)
_, err = jsoniter.Marshal(TestObject1{Obj: &TestObject2{}})
should.NotNil(err)
})
t.Run("decode null is valid", func(t *testing.T) {
should := require.New(t)
var obj TestObject1
should.Nil(json.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
should.Nil(jsoniter.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
})
t.Run("decode not null is invalid", func(t *testing.T) {
should := require.New(t)
var obj TestObject1
should.NotNil(json.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
should.NotNil(jsoniter.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
})
}
func TestEOF(t *testing.T) {
var s string
err := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(&bytes.Buffer{}).Decode(&s)
assert.Equal(t, io.EOF, err)
}
func TestDecodeErrorType(t *testing.T) {
should := require.New(t)
var err error
should.Nil(jsoniter.Unmarshal([]byte("null"), &err))
should.NotNil(jsoniter.Unmarshal([]byte("123"), &err))
}
func Test_decode_slash(t *testing.T) {
should := require.New(t)
var obj interface{}
should.NotNil(json.Unmarshal([]byte("\\"), &obj))
should.NotNil(jsoniter.UnmarshalFromString("\\", &obj))
}
func Test_NilInput(t *testing.T) {
var jb []byte // nil
var out string
err := jsoniter.Unmarshal(jb, &out)
if err == nil {
t.Errorf("Expected error")
}
}
func Test_EmptyInput(t *testing.T) {
jb := []byte("")
var out string
err := jsoniter.Unmarshal(jb, &out)
if err == nil {
t.Errorf("Expected error")
}
}

View File

@ -0,0 +1,51 @@
package test
import (
"encoding/json"
"math/big"
)
func init() {
var pRawMessage = func(val json.RawMessage) *json.RawMessage {
return &val
}
nilMap := map[string]string(nil)
marshalCases = append(marshalCases,
map[string]interface{}{"abc": 1},
map[string]MyInterface{"hello": MyString("world")},
map[*big.Float]string{big.NewFloat(1.2): "2"},
map[string]interface{}{
"3": 3,
"1": 1,
"2": 2,
},
map[uint64]interface{}{
uint64(1): "a",
uint64(2): "a",
uint64(4): "a",
},
nilMap,
&nilMap,
map[string]*json.RawMessage{"hello": pRawMessage(json.RawMessage("[]"))},
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*map[string]string)(nil),
input: `{"k\"ey": "val"}`,
}, unmarshalCase{
ptr: (*map[string]string)(nil),
input: `null`,
}, unmarshalCase{
ptr: (*map[string]*json.RawMessage)(nil),
input: "{\"test\":[{\"key\":\"value\"}]}",
})
}
type MyInterface interface {
Hello() string
}
type MyString string
func (ms MyString) Hello() string {
return string(ms)
}

View File

@ -0,0 +1,84 @@
package test
import (
"encoding"
"encoding/json"
)
func init() {
jm := json.Marshaler(jmOfStruct{})
tm1 := encoding.TextMarshaler(tmOfStruct{})
tm2 := encoding.TextMarshaler(&tmOfStructInt{})
marshalCases = append(marshalCases,
jmOfStruct{},
&jm,
tmOfStruct{},
&tm1,
tmOfStructInt{},
&tm2,
map[tmOfStruct]int{
{}: 100,
},
map[*tmOfStruct]int{
{}: 100,
},
map[encoding.TextMarshaler]int{
tm1: 100,
},
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*tmOfMap)(nil),
input: `"{1:2}"`,
}, unmarshalCase{
ptr: (*tmOfMapPtr)(nil),
input: `"{1:2}"`,
})
}
type jmOfStruct struct {
F2 chan []byte
}
func (q jmOfStruct) MarshalJSON() ([]byte, error) {
return []byte(`""`), nil
}
func (q *jmOfStruct) UnmarshalJSON(value []byte) error {
return nil
}
type tmOfStruct struct {
F2 chan []byte
}
func (q tmOfStruct) MarshalText() ([]byte, error) {
return []byte(`""`), nil
}
func (q *tmOfStruct) UnmarshalText(value []byte) error {
return nil
}
type tmOfStructInt struct {
Field2 int
}
func (q *tmOfStructInt) MarshalText() ([]byte, error) {
return []byte(`"abc"`), nil
}
func (q *tmOfStructInt) UnmarshalText(value []byte) error {
return nil
}
type tmOfMap map[int]int
func (q tmOfMap) UnmarshalText(value []byte) error {
return nil
}
type tmOfMapPtr map[int]int
func (q *tmOfMapPtr) UnmarshalText(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(""))
}

View File

@ -0,0 +1,39 @@
package test
func init() {
var pInt = func(val int) *int {
return &val
}
marshalCases = append(marshalCases,
(*int)(nil),
pInt(100),
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
obj: func() interface{} {
var i int
return &i
},
input: "null",
}, unmarshalCase{
obj: func() interface{} {
var i *int
return &i
},
input: "10",
}, unmarshalCase{
obj: func() interface{} {
var i int
pi := &i
return &pi
},
input: "null",
}, unmarshalCase{
obj: func() interface{} {
var i int
pi := &i
ppi := &pi
return &ppi
},
input: "null",
})
}

View File

@ -0,0 +1,21 @@
package test
import (
"encoding/json"
)
func init() {
marshalCases = append(marshalCases,
json.RawMessage("{}"),
selectedMarshalCase{struct {
Env string `json:"env"`
Extra json.RawMessage `json:"extra,omitempty"`
}{
Env: "jfdk",
}},
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*json.RawMessage)(nil),
input: `[1,2,3]`,
})
}

View File

@ -0,0 +1,27 @@
package test
func init() {
nilSlice := []string(nil)
marshalCases = append(marshalCases,
[]interface{}{"hello"},
nilSlice,
&nilSlice,
[]byte{1, 2, 3},
)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*[]string)(nil),
input: "null",
}, unmarshalCase{
ptr: (*[]string)(nil),
input: "[]",
}, unmarshalCase{
ptr: (*[]byte)(nil),
input: "[1,2,3]",
}, unmarshalCase{
ptr: (*[]byte)(nil),
input: `"aGVsbG8="`,
}, unmarshalCase{
ptr: (*[]byte)(nil),
input: `"c3ViamVjdHM\/X2Q9MQ=="`,
})
}

View File

@ -0,0 +1,88 @@
package test
import (
"encoding/json"
"github.com/json-iterator/go"
"testing"
"unicode/utf8"
)
func init() {
marshalCases = append(marshalCases,
`>`,
`"数字山谷"`,
"he\u2029\u2028he",
)
for i := 0; i < utf8.RuneSelf; i++ {
marshalCases = append(marshalCases, string([]byte{byte(i)}))
}
}
func Test_read_string(t *testing.T) {
badInputs := []string{
``,
`"`,
`"\"`,
`"\\\"`,
"\"\n\"",
`"\U0001f64f"`,
`"\uD83D\u00"`,
}
for i := 0; i < 32; i++ {
// control characters are invalid
badInputs = append(badInputs, string([]byte{'"', byte(i), '"'}))
}
for _, input := range badInputs {
testReadString(t, input, "", true, "json.Unmarshal", json.Unmarshal)
testReadString(t, input, "", true, "jsoniter.Unmarshal", jsoniter.Unmarshal)
testReadString(t, input, "", true, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
}
goodInputs := []struct {
input string
expectValue string
}{
{`""`, ""},
{`"a"`, "a"},
{`null`, ""},
{`"Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"`, "Iñtërnâtiônàlizætiøn,💝🐹🌇⛔"},
{`"\uD83D"`, string([]byte{239, 191, 189})},
{`"\uD83D\\"`, string([]byte{239, 191, 189, '\\'})},
{`"\uD83D\ub000"`, string([]byte{239, 191, 189, 235, 128, 128})},
{`"\uD83D\ude04"`, "😄"},
{`"\uDEADBEEF"`, string([]byte{239, 191, 189, 66, 69, 69, 70})},
{`"hel\"lo"`, `hel"lo`},
{`"hel\\\/lo"`, `hel\/lo`},
{`"hel\\blo"`, `hel\blo`},
{`"hel\\\blo"`, "hel\\\blo"},
{`"hel\\nlo"`, `hel\nlo`},
{`"hel\\\nlo"`, "hel\\\nlo"},
{`"hel\\tlo"`, `hel\tlo`},
{`"hel\\flo"`, `hel\flo`},
{`"hel\\\flo"`, "hel\\\flo"},
{`"hel\\\rlo"`, "hel\\\rlo"},
{`"hel\\\tlo"`, "hel\\\tlo"},
{`"\u4e2d\u6587"`, "中文"},
{`"\ud83d\udc4a"`, "\xf0\x9f\x91\x8a"},
}
for _, tc := range goodInputs {
testReadString(t, tc.input, tc.expectValue, false, "json.Unmarshal", json.Unmarshal)
testReadString(t, tc.input, tc.expectValue, false, "jsoniter.Unmarshal", jsoniter.Unmarshal)
testReadString(t, tc.input, tc.expectValue, false, "jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
}
}
func testReadString(t *testing.T, input string, expectValue string, expectError bool, marshalerName string, marshaler func([]byte, interface{}) error) {
var value string
err := marshaler([]byte(input), &value)
if expectError != (err != nil) {
t.Errorf("%q: %s: expected error %v, got %v", input, marshalerName, expectError, err)
return
}
if value != expectValue {
t.Errorf("%q: %s: expected %q, got %q", input, marshalerName, expectValue, value)
return
}
}

View File

@ -0,0 +1,237 @@
package test
import (
"bytes"
"encoding/json"
"time"
)
func init() {
var pString = func(val string) *string {
return &val
}
epoch := time.Unix(0, 0)
unmarshalCases = append(unmarshalCases, unmarshalCase{
ptr: (*struct {
Field interface{}
})(nil),
input: `{"Field": "hello"}`,
}, unmarshalCase{
ptr: (*struct {
Field interface{}
})(nil),
input: `{"Field": "hello"} `,
}, unmarshalCase{
ptr: (*struct {
Field int `json:"field"`
})(nil),
input: `{"field": null}`,
}, unmarshalCase{
ptr: (*struct {
ID int `json:"id"`
Payload map[string]interface{} `json:"payload"`
buf *bytes.Buffer
})(nil),
input: ` {"id":1, "payload":{"account":"123","password":"456"}}`,
}, unmarshalCase{
ptr: (*struct {
Field1 string
})(nil),
input: `{"Field\"1":"hello"}`,
}, unmarshalCase{
ptr: (*struct {
Field1 string
})(nil),
input: `{"\u0046ield1":"hello"}`,
}, unmarshalCase{
ptr: (*struct {
Field1 *string
Field2 *string
})(nil),
input: `{"field1": null, "field2": "world"}`,
}, unmarshalCase{
ptr: (*struct {
Field1 string
Field2 json.RawMessage
})(nil),
input: `{"field1": "hello", "field2":[1,2,3]}`,
}, unmarshalCase{
ptr: (*struct {
a int
b <-chan int
C int
d *time.Timer
})(nil),
input: `{"a": 444, "b":"bad", "C":256, "d":{"not":"a timer"}}`,
}, unmarshalCase{
ptr: (*struct {
A string
B string
C string
D string
E string
F string
G string
H string
I string
J string
K string
})(nil),
input: `{"a":"1","b":"2","c":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`,
}, unmarshalCase{
ptr: (*struct {
T float64 `json:"T"`
})(nil),
input: `{"t":10.0}`,
}, unmarshalCase{
ptr: (*struct {
T float64 `json:"T"`
})(nil),
input: `{"T":10.0}`,
}, unmarshalCase{
ptr: (*struct {
T float64 `json:"t"`
})(nil),
input: `{"T":10.0}`,
}, unmarshalCase{
ptr: (*struct {
KeyString string `json:"key_string"`
Type string `json:"type"`
Asks [][2]float64 `json:"asks"`
})(nil),
input: `{"key_string": "KEYSTRING","type": "TYPE","asks": [[1e+66,1]]}`,
})
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
}{},
struct {
*time.Time
}{&epoch},
struct {
*StructVarious
}{&StructVarious{}},
struct {
*StructVarious
Field int
}{nil, 10},
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")},
struct {
Field1 string `json:"field-1,omitempty"`
Field2 func() `json:"-"`
}{},
structRecursive{},
struct {
*CacheItem
// Omit bad keys
OmitMaxAge omit `json:"cacheAge,omitempty"`
// Add nice keys
MaxAge int `json:"max_age"`
}{
CacheItem: &CacheItem{
Key: "value",
MaxAge: 100,
},
MaxAge: 20,
},
structOrder{},
struct {
Field1 *string
Field2 *string
}{Field2: pString("world")},
struct {
a int
b <-chan int
C int
d *time.Timer
}{
a: 42,
b: make(<-chan int, 10),
C: 21,
d: time.NewTimer(10 * time.Second),
},
)
}
type StructVarious struct {
Field0 string
Field1 []string
Field2 map[string]interface{}
}
type structRecursive struct {
Field1 string
Me *structRecursive
}
type omit *struct{}
type CacheItem struct {
Key string `json:"key"`
MaxAge int `json:"cacheAge"`
}
type orderA struct {
Field2 string
}
type orderC struct {
Field5 string
}
type orderB struct {
Field4 string
orderC
Field6 string
}
type structOrder struct {
Field1 string
orderA
Field3 string
orderB
Field7 string
}

View File

@ -0,0 +1,80 @@
package test
import (
"encoding/json"
"fmt"
"github.com/json-iterator/go"
"github.com/modern-go/reflect2"
"github.com/stretchr/testify/require"
"testing"
)
type unmarshalCase struct {
obj func() interface{}
ptr interface{}
input string
selected bool
}
var unmarshalCases []unmarshalCase
var marshalCases = []interface{}{
nil,
}
type selectedMarshalCase struct {
marshalCase interface{}
}
func Test_unmarshal(t *testing.T) {
for _, testCase := range unmarshalCases {
if testCase.selected {
unmarshalCases = []unmarshalCase{testCase}
break
}
}
for i, testCase := range unmarshalCases {
t.Run(fmt.Sprintf("[%v]%s", i, testCase.input), func(t *testing.T) {
should := require.New(t)
var obj1 interface{}
var obj2 interface{}
if testCase.obj != nil {
obj1 = testCase.obj()
obj2 = testCase.obj()
} else {
valType := reflect2.TypeOfPtr(testCase.ptr).Elem()
obj1 = valType.New()
obj2 = valType.New()
}
err1 := json.Unmarshal([]byte(testCase.input), obj1)
should.NoError(err1, "json")
err2 := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(testCase.input), obj2)
should.NoError(err2, "jsoniter")
should.Equal(obj1, obj2)
})
}
}
func Test_marshal(t *testing.T) {
for _, testCase := range marshalCases {
selectedMarshalCase, found := testCase.(selectedMarshalCase)
if found {
marshalCases = []interface{}{selectedMarshalCase.marshalCase}
break
}
}
for i, testCase := range marshalCases {
var name string
if testCase != nil {
name = fmt.Sprintf("[%v]%v/%s", i, testCase, reflect2.TypeOf(testCase).String())
}
t.Run(name, func(t *testing.T) {
should := require.New(t)
output1, err1 := json.Marshal(testCase)
should.NoError(err1, "json")
output2, err2 := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(testCase)
should.NoError(err2, "jsoniter")
should.Equal(string(output1), string(output2))
})
}
}