config_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package test
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. "testing"
  7. jsoniter "github.com/json-iterator/go"
  8. "github.com/stretchr/testify/require"
  9. )
  10. func Test_use_number_for_unmarshal(t *testing.T) {
  11. should := require.New(t)
  12. api := jsoniter.Config{UseNumber: true}.Froze()
  13. var obj interface{}
  14. should.Nil(api.UnmarshalFromString("123", &obj))
  15. should.Equal(json.Number("123"), obj)
  16. }
  17. func Test_customize_float_marshal(t *testing.T) {
  18. should := require.New(t)
  19. json := jsoniter.Config{MarshalFloatWith6Digits: true}.Froze()
  20. str, err := json.MarshalToString(float32(1.23456789))
  21. should.Nil(err)
  22. should.Equal("1.234568", str)
  23. }
  24. func Test_max_depth(t *testing.T) {
  25. deepJSON := func(depth int) []byte {
  26. return []byte(strings.Repeat(`[`, depth) + strings.Repeat(`]`, depth))
  27. }
  28. tests := []struct {
  29. jsonDepth int
  30. cfgMaxDepth int
  31. expectedErr string
  32. }{
  33. // Test the default depth
  34. {jsonDepth: 10000, cfgMaxDepth: 0},
  35. {jsonDepth: 10001, cfgMaxDepth: 0, expectedErr: "max depth"},
  36. // Test max depth logic
  37. {jsonDepth: 5, cfgMaxDepth: 6},
  38. {jsonDepth: 5, cfgMaxDepth: 5},
  39. {jsonDepth: 5, cfgMaxDepth: 4, expectedErr: "max depth"},
  40. // Try a large depth without a limit
  41. {jsonDepth: 128000, cfgMaxDepth: -1},
  42. }
  43. for _, test := range tests {
  44. t.Run(fmt.Sprintf("jsonDepth:%v_cfgMaxDepth:%v", test.jsonDepth, test.cfgMaxDepth), func(t *testing.T) {
  45. should := require.New(t)
  46. cfg := jsoniter.Config{MaxDepth: test.cfgMaxDepth}.Froze()
  47. var val interface{}
  48. err := cfg.Unmarshal(deepJSON(test.jsonDepth), &val)
  49. if test.expectedErr != "" {
  50. should.Error(err)
  51. should.Contains(err.Error(), test.expectedErr)
  52. } else {
  53. should.NoError(err)
  54. }
  55. })
  56. }
  57. }
  58. func Test_customize_tag_key(t *testing.T) {
  59. type TestObject struct {
  60. Field string `orm:"field"`
  61. }
  62. should := require.New(t)
  63. json := jsoniter.Config{TagKey: "orm"}.Froze()
  64. str, err := json.MarshalToString(TestObject{"hello"})
  65. should.Nil(err)
  66. should.Equal(`{"field":"hello"}`, str)
  67. }
  68. func Test_read_large_number_as_interface(t *testing.T) {
  69. should := require.New(t)
  70. var val interface{}
  71. err := jsoniter.Config{UseNumber: true}.Froze().UnmarshalFromString(`123456789123456789123456789`, &val)
  72. should.Nil(err)
  73. output, err := jsoniter.MarshalToString(val)
  74. should.Nil(err)
  75. should.Equal(`123456789123456789123456789`, output)
  76. }
  77. type caseSensitiveStruct struct {
  78. A string `json:"a"`
  79. B string `json:"b,omitempty"`
  80. C *C `json:"C,omitempty"`
  81. }
  82. type C struct {
  83. D int64 `json:"D,omitempty"`
  84. E *E `json:"e,omitempty"`
  85. }
  86. type E struct {
  87. F string `json:"F,omitempty"`
  88. }
  89. func Test_CaseSensitive(t *testing.T) {
  90. should := require.New(t)
  91. testCases := []struct {
  92. input string
  93. expectedOutput string
  94. caseSensitive bool
  95. }{
  96. {
  97. input: `{"A":"foo","B":"bar"}`,
  98. expectedOutput: `{"a":"foo","b":"bar"}`,
  99. caseSensitive: false,
  100. },
  101. {
  102. input: `{"a":"foo","b":"bar"}`,
  103. expectedOutput: `{"a":"foo","b":"bar"}`,
  104. caseSensitive: true,
  105. },
  106. {
  107. input: `{"a":"foo","b":"bar","C":{"D":10}}`,
  108. expectedOutput: `{"a":"foo","b":"bar","C":{"D":10}}`,
  109. caseSensitive: true,
  110. },
  111. {
  112. input: `{"a":"foo","B":"bar","c":{"d":10}}`,
  113. expectedOutput: `{"a":"foo"}`,
  114. caseSensitive: true,
  115. },
  116. {
  117. input: `{"a":"foo","C":{"d":10}}`,
  118. expectedOutput: `{"a":"foo","C":{}}`,
  119. caseSensitive: true,
  120. },
  121. {
  122. input: `{"a":"foo","C":{"D":10,"e":{"f":"baz"}}}`,
  123. expectedOutput: `{"a":"foo","C":{"D":10,"e":{}}}`,
  124. caseSensitive: true,
  125. },
  126. {
  127. input: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
  128. expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
  129. caseSensitive: true,
  130. },
  131. {
  132. input: `{"A":"foo","c":{"d":10,"E":{"f":"baz"}}}`,
  133. expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
  134. caseSensitive: false,
  135. },
  136. }
  137. for _, tc := range testCases {
  138. val := caseSensitiveStruct{}
  139. err := jsoniter.Config{CaseSensitive: tc.caseSensitive}.Froze().UnmarshalFromString(tc.input, &val)
  140. should.Nil(err)
  141. output, err := jsoniter.MarshalToString(val)
  142. should.Nil(err)
  143. should.Equal(tc.expectedOutput, output)
  144. }
  145. }
  146. type structWithElevenFields struct {
  147. A string `json:"A,omitempty"`
  148. B string `json:"B,omitempty"`
  149. C string `json:"C,omitempty"`
  150. D string `json:"d,omitempty"`
  151. E string `json:"e,omitempty"`
  152. F string `json:"f,omitempty"`
  153. G string `json:"g,omitempty"`
  154. H string `json:"h,omitempty"`
  155. I string `json:"i,omitempty"`
  156. J string `json:"j,omitempty"`
  157. K string `json:"k,omitempty"`
  158. }
  159. func Test_CaseSensitive_MoreThanTenFields(t *testing.T) {
  160. should := require.New(t)
  161. testCases := []struct {
  162. input string
  163. expectedOutput string
  164. caseSensitive bool
  165. }{
  166. {
  167. input: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`,
  168. expectedOutput: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6","g":"7","h":"8","i":"9","j":"10","k":"11"}`,
  169. caseSensitive: true,
  170. },
  171. {
  172. input: `{"a":"1","b":"2","c":"3","D":"4","E":"5","F":"6"}`,
  173. expectedOutput: `{"A":"1","B":"2","C":"3","d":"4","e":"5","f":"6"}`,
  174. caseSensitive: false,
  175. },
  176. {
  177. input: `{"A":"1","b":"2","d":"4","E":"5"}`,
  178. expectedOutput: `{"A":"1","d":"4"}`,
  179. caseSensitive: true,
  180. },
  181. }
  182. for _, tc := range testCases {
  183. val := structWithElevenFields{}
  184. err := jsoniter.Config{CaseSensitive: tc.caseSensitive}.Froze().UnmarshalFromString(tc.input, &val)
  185. should.Nil(err)
  186. output, err := jsoniter.MarshalToString(val)
  187. should.Nil(err)
  188. should.Equal(tc.expectedOutput, output)
  189. }
  190. }
  191. type onlyTaggedFieldStruct struct {
  192. A string `json:"a"`
  193. B string
  194. FSimpl F `json:"f_simpl"`
  195. ISimpl I
  196. FPtr *F `json:"f_ptr"`
  197. IPtr *I
  198. F
  199. *I
  200. }
  201. type F struct {
  202. G string `json:"g"`
  203. H string
  204. }
  205. type I struct {
  206. J string `json:"j"`
  207. K string
  208. }
  209. func Test_OnlyTaggedField(t *testing.T) {
  210. should := require.New(t)
  211. obj := onlyTaggedFieldStruct{
  212. A: "a",
  213. B: "b",
  214. FSimpl: F{G: "g", H: "h"},
  215. ISimpl: I{J: "j", K: "k"},
  216. FPtr: &F{G: "g", H: "h"},
  217. IPtr: &I{J: "j", K: "k"},
  218. F: F{G: "g", H: "h"},
  219. I: &I{J: "j", K: "k"},
  220. }
  221. output, err := jsoniter.Config{OnlyTaggedField: true}.Froze().Marshal(obj)
  222. should.Nil(err)
  223. m := make(map[string]interface{})
  224. err = jsoniter.Unmarshal(output, &m)
  225. should.Nil(err)
  226. should.Equal(map[string]interface{}{
  227. "a": "a",
  228. "f_simpl": map[string]interface{}{
  229. "g": "g",
  230. },
  231. "f_ptr": map[string]interface{}{
  232. "g": "g",
  233. },
  234. "g": "g",
  235. "j": "j",
  236. }, m)
  237. }