2016-12-01 00:56:25 +08:00
|
|
|
package jsoniter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
2017-01-16 23:57:09 +08:00
|
|
|
"fmt"
|
2017-06-06 23:27:00 +08:00
|
|
|
"github.com/json-iterator/go/require"
|
|
|
|
"testing"
|
2017-06-15 23:54:43 +08:00
|
|
|
"unicode/utf8"
|
2016-12-01 00:56:25 +08:00
|
|
|
)
|
|
|
|
|
2017-01-16 23:57:09 +08:00
|
|
|
func Test_read_normal_string(t *testing.T) {
|
|
|
|
cases := map[string]string{
|
|
|
|
`"0123456789012345678901234567890123456789"`: `0123456789012345678901234567890123456789`,
|
2017-06-06 23:27:00 +08:00
|
|
|
`""`: ``,
|
2017-01-16 23:57:09 +08:00
|
|
|
`"hello"`: `hello`,
|
|
|
|
}
|
|
|
|
for input, output := range cases {
|
|
|
|
t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
|
|
|
|
should := require.New(t)
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := ParseString(ConfigDefault, input)
|
2017-01-16 23:57:09 +08:00
|
|
|
should.Equal(output, iter.ReadString())
|
|
|
|
})
|
|
|
|
t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
|
|
|
|
should := require.New(t)
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
|
2017-01-16 23:57:09 +08:00
|
|
|
should.Equal(output, iter.ReadString())
|
|
|
|
})
|
|
|
|
t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
|
|
|
|
should := require.New(t)
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := ParseString(ConfigDefault, input)
|
2017-01-16 23:57:09 +08:00
|
|
|
should.Equal(output, string(iter.ReadStringAsSlice()))
|
|
|
|
})
|
|
|
|
t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
|
|
|
|
should := require.New(t)
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
|
2017-01-16 23:57:09 +08:00
|
|
|
should.Equal(output, string(iter.ReadStringAsSlice()))
|
|
|
|
})
|
2016-12-01 00:56:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-16 23:57:09 +08:00
|
|
|
func Test_read_exotic_string(t *testing.T) {
|
|
|
|
cases := map[string]string{
|
2017-06-06 23:27:00 +08:00
|
|
|
`"hel\"lo"`: `hel"lo`,
|
|
|
|
`"hel\nlo"`: "hel\nlo",
|
2017-01-16 23:57:09 +08:00
|
|
|
`"\u4e2d\u6587"`: "中文",
|
|
|
|
`"\ud83d\udc4a"`: "\xf0\x9f\x91\x8a", // surrogate
|
|
|
|
}
|
|
|
|
for input, output := range cases {
|
|
|
|
t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
|
|
|
|
should := require.New(t)
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := ParseString(ConfigDefault, input)
|
2017-01-16 23:57:09 +08:00
|
|
|
should.Equal(output, iter.ReadString())
|
|
|
|
})
|
|
|
|
t.Run(fmt.Sprintf("%v:%v", input, output), func(t *testing.T) {
|
|
|
|
should := require.New(t)
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
|
2017-01-16 23:57:09 +08:00
|
|
|
should.Equal(output, iter.ReadString())
|
|
|
|
})
|
2016-12-06 14:23:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-23 08:33:43 +08:00
|
|
|
func Test_read_string_as_interface(t *testing.T) {
|
2017-01-21 16:09:38 +08:00
|
|
|
should := require.New(t)
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := ParseString(ConfigDefault, `"hello"`)
|
2017-01-21 16:09:38 +08:00
|
|
|
should.Equal("hello", iter.Read())
|
|
|
|
}
|
|
|
|
|
2017-01-07 12:28:16 +08:00
|
|
|
func Test_write_string(t *testing.T) {
|
|
|
|
should := require.New(t)
|
2017-01-22 00:04:08 +08:00
|
|
|
str, err := MarshalToString("hello")
|
|
|
|
should.Equal(`"hello"`, str)
|
|
|
|
should.Nil(err)
|
|
|
|
str, err = MarshalToString(`hel"lo`)
|
|
|
|
should.Equal(`"hel\"lo"`, str)
|
|
|
|
should.Nil(err)
|
2017-01-09 17:47:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func Test_write_val_string(t *testing.T) {
|
|
|
|
should := require.New(t)
|
|
|
|
buf := &bytes.Buffer{}
|
2017-06-17 10:21:37 +08:00
|
|
|
stream := NewStream(ConfigDefault, buf, 4096)
|
2017-01-09 17:47:21 +08:00
|
|
|
stream.WriteVal("hello")
|
|
|
|
stream.Flush()
|
|
|
|
should.Nil(stream.Error)
|
|
|
|
should.Equal(`"hello"`, buf.String())
|
2017-01-07 12:28:16 +08:00
|
|
|
}
|
|
|
|
|
2017-06-08 09:46:19 +08:00
|
|
|
func Test_decode_slash(t *testing.T) {
|
|
|
|
should := require.New(t)
|
|
|
|
var obj interface{}
|
2017-06-09 17:06:27 +08:00
|
|
|
should.NotNil(json.Unmarshal([]byte("\\"), &obj))
|
|
|
|
should.NotNil(UnmarshalFromString("\\", &obj))
|
2017-06-08 09:46:19 +08:00
|
|
|
}
|
|
|
|
|
2017-06-15 23:54:43 +08:00
|
|
|
func Test_html_escape(t *testing.T) {
|
|
|
|
should := require.New(t)
|
|
|
|
output, err := json.Marshal(`>`)
|
|
|
|
should.Nil(err)
|
|
|
|
should.Equal(`"\u003e"`, string(output))
|
|
|
|
output, err = ConfigCompatibleWithStandardLibrary.Marshal(`>`)
|
|
|
|
should.Nil(err)
|
|
|
|
should.Equal(`"\u003e"`, string(output))
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_string_encode_with_std(t *testing.T) {
|
|
|
|
should := require.New(t)
|
|
|
|
for i := 0; i < utf8.RuneSelf; i++ {
|
|
|
|
input := string([]byte{byte(i)})
|
|
|
|
stdOutputBytes, err := json.Marshal(input)
|
|
|
|
should.Nil(err)
|
|
|
|
stdOutput := string(stdOutputBytes)
|
|
|
|
jsoniterOutputBytes, err := ConfigCompatibleWithStandardLibrary.Marshal(input)
|
|
|
|
should.Nil(err)
|
|
|
|
jsoniterOutput := string(jsoniterOutputBytes)
|
|
|
|
should.Equal(stdOutput, jsoniterOutput)
|
|
|
|
}
|
|
|
|
}
|
2017-06-13 09:14:19 +08:00
|
|
|
|
2017-06-16 16:03:02 +08:00
|
|
|
func Test_string_encode_with_std_without_html_escape(t *testing.T) {
|
|
|
|
should := require.New(t)
|
|
|
|
for i := 0; i < utf8.RuneSelf; i++ {
|
|
|
|
input := string([]byte{byte(i)})
|
|
|
|
buf := &bytes.Buffer{}
|
|
|
|
encoder := json.NewEncoder(buf)
|
|
|
|
encoder.SetEscapeHTML(false)
|
|
|
|
err := encoder.Encode(input)
|
|
|
|
should.Nil(err)
|
|
|
|
stdOutput := buf.String()
|
2017-06-17 21:11:23 +08:00
|
|
|
stdOutput = stdOutput[:len(stdOutput)-1]
|
2017-06-16 16:03:02 +08:00
|
|
|
jsoniterOutputBytes, err := Marshal(input)
|
|
|
|
should.Nil(err)
|
|
|
|
jsoniterOutput := string(jsoniterOutputBytes)
|
|
|
|
should.Equal(stdOutput, jsoniterOutput)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-01 00:56:25 +08:00
|
|
|
func Benchmark_jsoniter_unicode(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := ParseString(ConfigDefault, `"\ud83d\udc4a"`)
|
2016-12-01 10:35:38 +08:00
|
|
|
iter.ReadString()
|
2016-12-01 00:56:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Benchmark_jsoniter_ascii(b *testing.B) {
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := NewIterator(ConfigDefault)
|
2017-01-16 23:43:20 +08:00
|
|
|
input := []byte(`"hello, world! hello, world!"`)
|
2016-12-06 14:23:59 +08:00
|
|
|
b.ResetTimer()
|
2016-12-01 00:56:25 +08:00
|
|
|
for n := 0; n < b.N; n++ {
|
2017-01-16 23:43:20 +08:00
|
|
|
iter.ResetBytes(input)
|
2016-12-01 10:35:38 +08:00
|
|
|
iter.ReadString()
|
2016-12-01 00:56:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-06 14:23:59 +08:00
|
|
|
func Benchmark_jsoniter_string_as_bytes(b *testing.B) {
|
2017-06-17 10:21:37 +08:00
|
|
|
iter := ParseString(ConfigDefault, `"hello, world!"`)
|
2016-12-06 14:23:59 +08:00
|
|
|
b.ResetTimer()
|
|
|
|
for n := 0; n < b.N; n++ {
|
2016-12-10 14:34:36 +08:00
|
|
|
iter.ResetBytes(iter.buf)
|
2017-01-16 23:57:09 +08:00
|
|
|
iter.ReadStringAsSlice()
|
2016-12-06 14:23:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-01 00:56:25 +08:00
|
|
|
func Benchmark_json_unicode(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
result := ""
|
|
|
|
json.Unmarshal([]byte(`"\ud83d\udc4a"`), &result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Benchmark_json_ascii(b *testing.B) {
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
result := ""
|
|
|
|
json.Unmarshal([]byte(`"hello"`), &result)
|
|
|
|
}
|
2017-01-05 21:23:08 +08:00
|
|
|
}
|