ソースを参照

consolidate mor tests

Tao Wen 7 年 前
コミット
8fa357ab7b

+ 22 - 0
api_tests/config_test.go

@@ -14,3 +14,25 @@ func Test_use_number_for_unmarshal(t *testing.T) {
 	should.Nil(api.UnmarshalFromString("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)
+}

+ 101 - 0
extension_tests/decoder_test.go

@@ -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())
+}

+ 75 - 0
extension_tests/extension_test.go

@@ -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)
+}

+ 0 - 113
jsoniter_bool_test.go

@@ -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)
-}

+ 0 - 342
jsoniter_customize_test.go

@@ -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)
-}

+ 0 - 87
jsoniter_demo_test.go

@@ -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)
-		}
-	}
-}

+ 0 - 42
jsoniter_encode_interface_test.go

@@ -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")
-}

+ 0 - 50
jsoniter_enum_marshaler_test.go

@@ -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)
-}

+ 0 - 46
jsoniter_fixed_array_test.go

@@ -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])
-}

+ 0 - 576
jsoniter_interface_test.go

@@ -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)
-}

+ 24 - 23
jsoniter_array_test.go → misc_tests/jsoniter_array_test.go

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

+ 47 - 0
misc_tests/jsoniter_bool_test.go

@@ -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())
+}

+ 95 - 0
misc_tests/jsoniter_float_test.go

@@ -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)
+	}
+}

+ 101 - 0
misc_tests/jsoniter_int_test.go

@@ -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)
+	}
+}

+ 224 - 0
misc_tests/jsoniter_interface_test.go

@@ -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)
+}

+ 14 - 0
type_tests/slice_test.go

@@ -71,5 +71,19 @@ func init() {
 			Map   map[string]string
 		})(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
+}

+ 13 - 0
type_tests/struct_embedded_test.go

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

+ 1 - 0
type_tests/struct_field_case_test.go

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

+ 3 - 0
type_tests/struct_tags_test.go

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

+ 34 - 1
type_tests/struct_test.go

@@ -1,5 +1,7 @@
 package test
 
+import "time"
+
 func init() {
 	testCases = append(testCases,
 		(*struct1Alias)(nil),
@@ -246,6 +248,13 @@ func init() {
 		(*struct {
 			F struct3
 		})(nil),
+		(*struct {
+			TF1 struct {
+				F1 withTime
+				F2 *withTime
+			}
+		})(nil),
+		(*DeeplyNested)(nil),
 	)
 }
 
@@ -274,4 +283,28 @@ type struct3 struct {
 	F1 stringAlias
 	F2 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
+}

+ 47 - 45
type_tests/type_test.go

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

+ 10 - 0
value_tests/array_test.go

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

+ 10 - 0
value_tests/bool_test.go

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

+ 20 - 107
jsoniter_float_test.go → value_tests/float_test.go

@@ -1,33 +1,15 @@
-// +build go1.8
-
-package jsoniter
+package test
 
 import (
-	"bytes"
-	"encoding/json"
 	"fmt"
-	"strconv"
 	"testing"
-
 	"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) {
 	inputs := []string{
 		`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
 		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
 			should := require.New(t)
-			iter := ParseString(ConfigDefault, input+",")
+			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 := ParseString(ConfigDefault, input+",")
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
 			expected, err := strconv.ParseFloat(input, 64)
 			should.Nil(err)
 			should.Equal(expected, iter.ReadFloat64())
@@ -52,14 +34,14 @@ func Test_read_float(t *testing.T) {
 		// streaming
 		t.Run(fmt.Sprintf("%v", input), func(t *testing.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)
 			should.Nil(err)
 			should.Equal(float32(expected), iter.ReadFloat32())
 		})
 		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
 			should := require.New(t)
-			iter := Parse(ConfigDefault, bytes.NewBufferString(input+","), 2)
+			iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input+","), 2)
 			val := float64(0)
 			err := json.Unmarshal([]byte(input), &val)
 			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) {
 	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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteFloat32Lossy(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -110,16 +80,16 @@ func Test_write_float32(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 10)
+	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 = NewStream(ConfigDefault, nil, 0)
+	stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
 	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) {
@@ -129,7 +99,7 @@ func Test_write_float64(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteFloat64Lossy(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -147,71 +117,14 @@ func Test_write_float64(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 10)
+	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 = NewStream(ConfigDefault, nil, 0)
+	stream = jsoniter.NewStream(jsoniter.ConfigDefault, nil, 0)
 	stream.WriteFloat64(float64(0.0000001))
-	should.Equal("1e-07", string(stream.buf))
-}
-
-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)
-	}
-}
+	should.Equal("1e-07", string(stream.Buffer()))
+}

+ 78 - 231
jsoniter_int_test.go → value_tests/int_test.go

@@ -1,69 +1,55 @@
-// +build go1.8
-
-package jsoniter
+package test
 
 import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
+	"github.com/stretchr/testify/require"
 	"strconv"
+	"fmt"
 	"testing"
-
-	"github.com/stretchr/testify/require"
+	"bytes"
+	"github.com/json-iterator/go"
 )
 
-func Test_read_uint64_invalid(t *testing.T) {
-	should := require.New(t)
-	iter := ParseString(ConfigDefault, ",")
-	iter.ReadUint64()
-	should.NotNil(iter.Error)
+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_read_int_from_null(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) {
+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 := ParseString(ConfigDefault, input)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
 			expected, err := strconv.ParseInt(input, 10, 8)
 			should.Nil(err)
 			should.Equal(int8(expected), iter.ReadInt8())
@@ -76,7 +62,7 @@ func Test_read_int16(t *testing.T) {
 	for _, input := range inputs {
 		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
 			should := require.New(t)
-			iter := ParseString(ConfigDefault, input)
+			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input)
 			expected, err := strconv.ParseInt(input, 10, 16)
 			should.Nil(err)
 			should.Equal(int16(expected), iter.ReadInt16())
@@ -89,14 +75,14 @@ func Test_read_int32(t *testing.T) {
 	for _, input := range inputs {
 		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
 			should := require.New(t)
-			iter := ParseString(ConfigDefault, input)
+			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 := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
+			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())
@@ -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) {
 	should := require.New(t)
 	inputArr := []string{"123451", "-123451"}
 	for _, s := range inputArr {
-		iter := ParseString(ConfigDefault, s)
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iter.ReadInt8()
 		should.NotNil(iter.Error)
 
-		iterU := ParseString(ConfigDefault, s)
+		iterU := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iterU.ReadUint8()
 		should.NotNil(iterU.Error)
 
@@ -136,33 +106,33 @@ func Test_read_int_overflow(t *testing.T) {
 
 	inputArr = []string{"12345678912", "-12345678912"}
 	for _, s := range inputArr {
-		iter := ParseString(ConfigDefault, s)
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iter.ReadInt16()
 		should.NotNil(iter.Error)
 
-		iterUint := ParseString(ConfigDefault, s)
+		iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iterUint.ReadUint16()
 		should.NotNil(iterUint.Error)
 	}
 
 	inputArr = []string{"3111111111", "-3111111111", "1234232323232323235678912", "-1234567892323232323212"}
 	for _, s := range inputArr {
-		iter := ParseString(ConfigDefault, s)
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iter.ReadInt32()
 		should.NotNil(iter.Error)
 
-		iterUint := ParseString(ConfigDefault, s)
+		iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iterUint.ReadUint32()
 		should.NotNil(iterUint.Error)
 	}
 
 	inputArr = []string{"9223372036854775811", "-9523372036854775807", "1234232323232323235678912", "-1234567892323232323212"}
 	for _, s := range inputArr {
-		iter := ParseString(ConfigDefault, s)
+		iter := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iter.ReadInt64()
 		should.NotNil(iter.Error)
 
-		iterUint := ParseString(ConfigDefault, s)
+		iterUint := jsoniter.ParseString(jsoniter.ConfigDefault, s)
 		iterUint.ReadUint64()
 		should.NotNil(iterUint.Error)
 	}
@@ -173,14 +143,14 @@ func Test_read_int64(t *testing.T) {
 	for _, input := range inputs {
 		t.Run(fmt.Sprintf("%v", input), func(t *testing.T) {
 			should := require.New(t)
-			iter := ParseString(ConfigDefault, input)
+			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 := Parse(ConfigDefault, bytes.NewBufferString(input), 2)
+			iter := jsoniter.Parse(jsoniter.ConfigDefault, bytes.NewBufferString(input), 2)
 			expected, err := strconv.ParseInt(input, 10, 64)
 			should.Nil(err)
 			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) {
 	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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteUint8(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -227,7 +183,7 @@ func Test_write_uint8(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 3)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 3)
 	stream.WriteRaw("a")
 	stream.WriteUint8(100) // should clear buffer
 	stream.Flush()
@@ -241,7 +197,7 @@ func Test_write_int8(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteInt8(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -259,7 +215,7 @@ func Test_write_int8(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 4)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4)
 	stream.WriteRaw("a")
 	stream.WriteInt8(-100) // should clear buffer
 	stream.Flush()
@@ -273,7 +229,7 @@ func Test_write_uint16(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteUint16(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -291,7 +247,7 @@ func Test_write_uint16(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 5)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 5)
 	stream.WriteRaw("a")
 	stream.WriteUint16(10000) // should clear buffer
 	stream.Flush()
@@ -305,7 +261,7 @@ func Test_write_int16(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteInt16(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -323,7 +279,7 @@ func Test_write_int16(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 6)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 6)
 	stream.WriteRaw("a")
 	stream.WriteInt16(-10000) // should clear buffer
 	stream.Flush()
@@ -337,7 +293,7 @@ func Test_write_uint32(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteUint32(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -355,7 +311,7 @@ func Test_write_uint32(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 10)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
 	stream.WriteRaw("a")
 	stream.WriteUint32(0xffffffff) // should clear buffer
 	stream.Flush()
@@ -369,7 +325,7 @@ func Test_write_int32(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteInt32(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -387,7 +343,7 @@ func Test_write_int32(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 11)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 11)
 	stream.WriteRaw("a")
 	stream.WriteInt32(-0x7fffffff) // should clear buffer
 	stream.Flush()
@@ -403,7 +359,7 @@ func Test_write_uint64(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteUint64(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -421,7 +377,7 @@ func Test_write_uint64(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 10)
+	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 10)
 	stream.WriteRaw("a")
 	stream.WriteUint64(0xffffffff) // should clear buffer
 	stream.Flush()
@@ -437,7 +393,7 @@ func Test_write_int64(t *testing.T) {
 		t.Run(fmt.Sprintf("%v", val), func(t *testing.T) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteInt64(val)
 			stream.Flush()
 			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) {
 			should := require.New(t)
 			buf := &bytes.Buffer{}
-			stream := NewStream(ConfigDefault, buf, 4096)
+			stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
 			stream.WriteVal(val)
 			stream.Flush()
 			should.Nil(stream.Error)
@@ -455,119 +411,10 @@ func Test_write_int64(t *testing.T) {
 	}
 	should := require.New(t)
 	buf := &bytes.Buffer{}
-	stream := NewStream(ConfigDefault, buf, 10)
+	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())
-}
-
-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 - 0
value_tests/map_test.go

@@ -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)
+}

+ 19 - 0
value_tests/marshaler_test.go

@@ -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
+}

+ 17 - 0
value_tests/number_test.go

@@ -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 - 0
value_tests/ptr_test.go

@@ -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"),
+	)
+}

+ 9 - 0
value_tests/raw_message_test.go

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

+ 5 - 0
value_tests/slice_test.go

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

+ 82 - 0
value_tests/struct_test.go

@@ -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 - 0
value_tests/value_test.go

@@ -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))
+	}
+}