Jelajahi Sumber

#142 decode struct field should be case insensitive, the bug only happen for struct with more than 10 fields

Tao Wen 8 tahun lalu
induk
melakukan
24ecaff2a1

+ 2 - 1
feature_reflect_object.go

@@ -5,6 +5,7 @@ import (
 	"io"
 	"reflect"
 	"unsafe"
+	"strings"
 )
 
 func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
@@ -101,7 +102,7 @@ func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
 	}
 	fields := map[string]*structFieldDecoder{}
 	for k, binding := range bindings {
-		fields[k] = binding.Decoder.(*structFieldDecoder)
+		fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
 	}
 	return createStructDecoder(typ, fields)
 }

+ 2 - 1
feature_reflect_struct_decoder.go

@@ -5,6 +5,7 @@ import (
 	"io"
 	"reflect"
 	"unsafe"
+	"strings"
 )
 
 func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) {
@@ -437,7 +438,7 @@ func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
 	for iter.nextToken() == ',' {
 		fieldBytes = iter.readObjectFieldAsBytes()
 		field = *(*string)(unsafe.Pointer(&fieldBytes))
-		fieldDecoder = decoder.fields[field]
+		fieldDecoder = decoder.fields[strings.ToLower(field)]
 		if fieldDecoder == nil {
 			iter.Skip()
 		} else {

+ 0 - 261
jsoniter_object_test.go

@@ -95,267 +95,6 @@ func Test_write_object(t *testing.T) {
 	should.Equal("{\n  \"hello\": 1,\n  \"world\": 2\n}", buf.String())
 }
 
-func Test_decode_one_field_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"field1": "hello"}`, &obj))
-	should.Equal("hello", obj.Field1)
-}
-
-func Test_decode_two_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-}
-
-func Test_decode_three_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-		Field3 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-}
-
-func Test_decode_four_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-		Field3 string
-		Field4 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-}
-
-func Test_decode_five_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-		Field3 string
-		Field4 string
-		Field5 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-	should.Equal("e", obj.Field5)
-}
-
-func Test_decode_six_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-		Field3 string
-		Field4 string
-		Field5 string
-		Field6 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field6": "x"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-	should.Equal("e", obj.Field5)
-	should.Equal("x", obj.Field6)
-}
-
-func Test_decode_seven_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-		Field3 string
-		Field4 string
-		Field5 string
-		Field6 string
-		Field7 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field6": "x", "Field7":"y"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-	should.Equal("e", obj.Field5)
-	should.Equal("x", obj.Field6)
-	should.Equal("y", obj.Field7)
-}
-
-func Test_decode_eight_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-		Field3 string
-		Field4 string
-		Field5 string
-		Field6 string
-		Field7 string
-		Field8 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field8":"1", "Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field6": "x", "Field7":"y"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-	should.Equal("e", obj.Field5)
-	should.Equal("x", obj.Field6)
-	should.Equal("y", obj.Field7)
-	should.Equal("1", obj.Field8)
-}
-
-func Test_decode_nine_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string
-		Field2 string
-		Field3 string
-		Field4 string
-		Field5 string
-		Field6 string
-		Field7 string
-		Field8 string
-		Field9 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field8" : "zzzzzzzzzzz", "Field7": "zz", "Field6" : "xx", "Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field9":"f"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-	should.Equal("e", obj.Field5)
-	should.Equal("xx", obj.Field6)
-	should.Equal("zz", obj.Field7)
-	should.Equal("zzzzzzzzzzz", obj.Field8)
-	should.Equal("f", obj.Field9)
-}
-
-func Test_decode_ten_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1  string
-		Field2  string
-		Field3  string
-		Field4  string
-		Field5  string
-		Field6  string
-		Field7  string
-		Field8  string
-		Field9  string
-		Field10 string
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field10":"x", "Field9": "x", "Field8":"x", "Field7":"x", "Field6":"x", "Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-	should.Equal("e", obj.Field5)
-	should.Equal("x", obj.Field6)
-	should.Equal("x", obj.Field7)
-	should.Equal("x", obj.Field8)
-	should.Equal("x", obj.Field9)
-	should.Equal("x", obj.Field10)
-}
-
-func Test_decode_more_than_ten_fields_struct(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1  string
-		Field2  string
-		Field3  string
-		Field4  string
-		Field5  string
-		Field6  string
-		Field7  string
-		Field8  string
-		Field9  string
-		Field10 string
-		Field11 int
-	}
-	obj := TestObject{}
-	should.Nil(UnmarshalFromString(`{}`, &obj))
-	should.Equal("", obj.Field1)
-	should.Nil(UnmarshalFromString(`{"Field11":1, "Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e"}`, &obj))
-	should.Equal("a", obj.Field1)
-	should.Equal("stream", obj.Field2)
-	should.Equal("c", obj.Field3)
-	should.Equal("d", obj.Field4)
-	should.Equal("e", obj.Field5)
-	should.Equal(1, obj.Field11)
-}
-
-func Test_decode_struct_field_with_tag(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 string `json:"field-1"`
-		Field2 string `json:"-"`
-		Field3 int    `json:",string"`
-	}
-	obj := TestObject{Field2: "world"}
-	UnmarshalFromString(`{"field-1": "hello", "field2": "", "Field3": "100"}`, &obj)
-	should.Equal("hello", obj.Field1)
-	should.Equal("world", obj.Field2)
-	should.Equal(100, obj.Field3)
-}
-
-func Test_decode_struct_field_with_tag_string(t *testing.T) {
-	should := require.New(t)
-	type TestObject struct {
-		Field1 int `json:",string"`
-	}
-	obj := TestObject{Field1: 100}
-	should.Nil(UnmarshalFromString(`{"Field1": "100"}`, &obj))
-	should.Equal(100, obj.Field1)
-}
-
 func Test_write_val_zero_field_struct(t *testing.T) {
 	should := require.New(t)
 	type TestObject struct {

+ 267 - 0
jsoniter_struct_decoder_test.go

@@ -0,0 +1,267 @@
+package jsoniter
+
+import (
+	"testing"
+	"github.com/stretchr/testify/require"
+)
+
+func Test_decode_one_field_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"field1": "hello"}`, &obj))
+	should.Equal("hello", obj.Field1)
+}
+
+func Test_decode_two_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+}
+
+func Test_decode_three_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+		Field3 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+}
+
+func Test_decode_four_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+		Field3 string
+		Field4 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+}
+
+func Test_decode_five_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+		Field3 string
+		Field4 string
+		Field5 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+	should.Equal("e", obj.Field5)
+}
+
+func Test_decode_six_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+		Field3 string
+		Field4 string
+		Field5 string
+		Field6 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field6": "x"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+	should.Equal("e", obj.Field5)
+	should.Equal("x", obj.Field6)
+}
+
+func Test_decode_seven_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+		Field3 string
+		Field4 string
+		Field5 string
+		Field6 string
+		Field7 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field6": "x", "Field7":"y"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+	should.Equal("e", obj.Field5)
+	should.Equal("x", obj.Field6)
+	should.Equal("y", obj.Field7)
+}
+
+func Test_decode_eight_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+		Field3 string
+		Field4 string
+		Field5 string
+		Field6 string
+		Field7 string
+		Field8 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field8":"1", "Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field6": "x", "Field7":"y"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+	should.Equal("e", obj.Field5)
+	should.Equal("x", obj.Field6)
+	should.Equal("y", obj.Field7)
+	should.Equal("1", obj.Field8)
+}
+
+func Test_decode_nine_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string
+		Field2 string
+		Field3 string
+		Field4 string
+		Field5 string
+		Field6 string
+		Field7 string
+		Field8 string
+		Field9 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field8" : "zzzzzzzzzzz", "Field7": "zz", "Field6" : "xx", "Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e", "Field9":"f"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+	should.Equal("e", obj.Field5)
+	should.Equal("xx", obj.Field6)
+	should.Equal("zz", obj.Field7)
+	should.Equal("zzzzzzzzzzz", obj.Field8)
+	should.Equal("f", obj.Field9)
+}
+
+func Test_decode_ten_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1  string
+		Field2  string
+		Field3  string
+		Field4  string
+		Field5  string
+		Field6  string
+		Field7  string
+		Field8  string
+		Field9  string
+		Field10 string
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"Field10":"x", "Field9": "x", "Field8":"x", "Field7":"x", "Field6":"x", "Field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+	should.Equal("e", obj.Field5)
+	should.Equal("x", obj.Field6)
+	should.Equal("x", obj.Field7)
+	should.Equal("x", obj.Field8)
+	should.Equal("x", obj.Field9)
+	should.Equal("x", obj.Field10)
+}
+
+func Test_decode_more_than_ten_fields_struct(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1  string
+		Field2  string
+		Field3  string
+		Field4  string
+		Field5  string
+		Field6  string
+		Field7  string
+		Field8  string
+		Field9  string
+		Field10 string
+		Field11 int
+	}
+	obj := TestObject{}
+	should.Nil(UnmarshalFromString(`{}`, &obj))
+	should.Equal("", obj.Field1)
+	should.Nil(UnmarshalFromString(`{"field11":1, "field1": "a", "Field2": "stream", "Field3": "c", "Field4": "d", "Field5": "e"}`, &obj))
+	should.Equal("a", obj.Field1)
+	should.Equal("stream", obj.Field2)
+	should.Equal("c", obj.Field3)
+	should.Equal("d", obj.Field4)
+	should.Equal("e", obj.Field5)
+	should.Equal(1, obj.Field11)
+}
+
+func Test_decode_struct_field_with_tag(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 string `json:"field-1"`
+		Field2 string `json:"-"`
+		Field3 int    `json:",string"`
+	}
+	obj := TestObject{Field2: "world"}
+	UnmarshalFromString(`{"field-1": "hello", "field2": "", "Field3": "100"}`, &obj)
+	should.Equal("hello", obj.Field1)
+	should.Equal("world", obj.Field2)
+	should.Equal(100, obj.Field3)
+}
+
+func Test_decode_struct_field_with_tag_string(t *testing.T) {
+	should := require.New(t)
+	type TestObject struct {
+		Field1 int `json:",string"`
+	}
+	obj := TestObject{Field1: 100}
+	should.Nil(UnmarshalFromString(`{"Field1": "100"}`, &obj))
+	should.Equal(100, obj.Field1)
+}