jsoniter_customize_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. package jsoniter
  2. import (
  3. "encoding/json"
  4. "github.com/json-iterator/go/require"
  5. "reflect"
  6. "strconv"
  7. "testing"
  8. "time"
  9. "unsafe"
  10. )
  11. func Test_customize_type_decoder(t *testing.T) {
  12. RegisterTypeDecoder("time.Time", func(ptr unsafe.Pointer, iter *Iterator) {
  13. t, err := time.ParseInLocation("2006-01-02 15:04:05", iter.ReadString(), time.UTC)
  14. if err != nil {
  15. iter.Error = err
  16. return
  17. }
  18. *((*time.Time)(ptr)) = t
  19. })
  20. defer CleanDecoders()
  21. val := time.Time{}
  22. err := Unmarshal([]byte(`"2016-12-05 08:43:28"`), &val)
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. year, month, day := val.Date()
  27. if year != 2016 || month != 12 || day != 5 {
  28. t.Fatal(val)
  29. }
  30. }
  31. func Test_customize_type_encoder(t *testing.T) {
  32. should := require.New(t)
  33. RegisterTypeEncoder("time.Time", func(ptr unsafe.Pointer, stream *Stream) {
  34. t := *((*time.Time)(ptr))
  35. stream.WriteString(t.UTC().Format("2006-01-02 15:04:05"))
  36. })
  37. defer CleanEncoders()
  38. val := time.Unix(0, 0)
  39. str, err := MarshalToString(val)
  40. should.Nil(err)
  41. should.Equal(`"1970-01-01 00:00:00"`, str)
  42. }
  43. func Test_customize_byte_array_encoder(t *testing.T) {
  44. CleanEncoders()
  45. should := require.New(t)
  46. RegisterTypeEncoder("[]uint8", func(ptr unsafe.Pointer, stream *Stream) {
  47. t := *((*[]byte)(ptr))
  48. stream.WriteString(string(t))
  49. })
  50. defer CleanEncoders()
  51. val := []byte("abc")
  52. str, err := MarshalToString(val)
  53. should.Nil(err)
  54. should.Equal(`"abc"`, str)
  55. }
  56. func Test_customize_float_marshal(t *testing.T) {
  57. should := require.New(t)
  58. EnableLossyFloatMarshalling()
  59. defer CleanEncoders()
  60. str, err := MarshalToString(float32(1.23456789))
  61. should.Nil(err)
  62. should.Equal("1.234568", str)
  63. }
  64. type Tom struct {
  65. field1 string
  66. }
  67. func Test_customize_field_decoder(t *testing.T) {
  68. RegisterFieldDecoder("jsoniter.Tom", "field1", func(ptr unsafe.Pointer, iter *Iterator) {
  69. *((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
  70. })
  71. defer CleanDecoders()
  72. tom := Tom{}
  73. err := Unmarshal([]byte(`{"field1": 100}`), &tom)
  74. if err != nil {
  75. t.Fatal(err)
  76. }
  77. }
  78. type TestObject1 struct {
  79. field1 string
  80. }
  81. func Test_customize_field_by_extension(t *testing.T) {
  82. should := require.New(t)
  83. RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc) {
  84. if type_.String() == "jsoniter.TestObject1" && field.Name == "field1" {
  85. encode := func(ptr unsafe.Pointer, stream *Stream) {
  86. str := *((*string)(ptr))
  87. val, _ := strconv.Atoi(str)
  88. stream.WriteInt(val)
  89. }
  90. decode := func(ptr unsafe.Pointer, iter *Iterator) {
  91. *((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
  92. }
  93. return []string{"field-1"}, encode, decode
  94. }
  95. return nil, nil, nil
  96. })
  97. obj := TestObject1{}
  98. err := UnmarshalFromString(`{"field-1": 100}`, &obj)
  99. should.Nil(err)
  100. should.Equal("100", obj.field1)
  101. str, err := MarshalToString(obj)
  102. should.Nil(err)
  103. should.Equal(`{"field-1":100}`, str)
  104. }
  105. func Test_unexported_fields(t *testing.T) {
  106. EnableUnexportedStructFieldsSupport()
  107. should := require.New(t)
  108. type TestObject struct {
  109. field1 string
  110. field2 string `json:"field-2"`
  111. }
  112. obj := TestObject{}
  113. obj.field1 = "hello"
  114. should.Nil(UnmarshalFromString(`{}`, &obj))
  115. should.Equal("hello", obj.field1)
  116. should.Nil(UnmarshalFromString(`{"field1": "world", "field-2": "abc"}`, &obj))
  117. should.Equal("world", obj.field1)
  118. should.Equal("abc", obj.field2)
  119. str, err := MarshalToString(obj)
  120. should.Nil(err)
  121. should.Contains(str, `"field-2":"abc"`)
  122. }
  123. type ObjectImplementedMarshaler int
  124. func (obj *ObjectImplementedMarshaler) MarshalJSON() ([]byte, error) {
  125. return []byte(`"hello"`), nil
  126. }
  127. func Test_marshaler(t *testing.T) {
  128. type TestObject struct {
  129. Field *ObjectImplementedMarshaler
  130. }
  131. should := require.New(t)
  132. val := ObjectImplementedMarshaler(100)
  133. obj := TestObject{&val}
  134. bytes, err := json.Marshal(obj)
  135. should.Nil(err)
  136. should.Equal(`{"Field":"hello"}`, string(bytes))
  137. str, err := MarshalToString(obj)
  138. should.Nil(err)
  139. should.Equal(`{"Field":"hello"}`, str)
  140. }
  141. func Test_marshaler_and_encoder(t *testing.T) {
  142. type TestObject struct {
  143. Field *ObjectImplementedMarshaler
  144. }
  145. should := require.New(t)
  146. RegisterTypeEncoder("jsoniter.ObjectImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) {
  147. stream.WriteString("hello from encoder")
  148. })
  149. val := ObjectImplementedMarshaler(100)
  150. obj := TestObject{&val}
  151. bytes, err := json.Marshal(obj)
  152. should.Nil(err)
  153. should.Equal(`{"Field":"hello"}`, string(bytes))
  154. str, err := MarshalToString(obj)
  155. should.Nil(err)
  156. should.Equal(`{"Field":"hello from encoder"}`, str)
  157. }
  158. type ObjectImplementedUnmarshaler int
  159. func (obj *ObjectImplementedUnmarshaler) UnmarshalJSON([]byte) error {
  160. *obj = 100
  161. return nil
  162. }
  163. func Test_unmarshaler(t *testing.T) {
  164. type TestObject struct {
  165. Field *ObjectImplementedUnmarshaler
  166. Field2 string
  167. }
  168. should := require.New(t)
  169. obj := TestObject{}
  170. val := ObjectImplementedUnmarshaler(0)
  171. obj.Field = &val
  172. err := json.Unmarshal([]byte(`{"Field":"hello"}`), &obj)
  173. should.Nil(err)
  174. should.Equal(100, int(*obj.Field))
  175. err = Unmarshal([]byte(`{"Field":"hello"}`), &obj)
  176. should.Nil(err)
  177. should.Equal(100, int(*obj.Field))
  178. }
  179. func Test_unmarshaler_and_decoder(t *testing.T) {
  180. type TestObject struct {
  181. Field *ObjectImplementedUnmarshaler
  182. Field2 string
  183. }
  184. should := require.New(t)
  185. RegisterTypeDecoder("jsoniter.ObjectImplementedUnmarshaler", func(ptr unsafe.Pointer, iter *Iterator) {
  186. *(*ObjectImplementedUnmarshaler)(ptr) = 10
  187. iter.Skip()
  188. })
  189. obj := TestObject{}
  190. val := ObjectImplementedUnmarshaler(0)
  191. obj.Field = &val
  192. err := json.Unmarshal([]byte(`{"Field":"hello"}`), &obj)
  193. should.Nil(err)
  194. should.Equal(100, int(*obj.Field))
  195. err = Unmarshal([]byte(`{"Field":"hello"}`), &obj)
  196. should.Nil(err)
  197. should.Equal(10, int(*obj.Field))
  198. }