jsoniter_interface_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. package jsoniter
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "testing"
  6. "unsafe"
  7. "github.com/stretchr/testify/require"
  8. )
  9. func Test_write_array_of_interface(t *testing.T) {
  10. should := require.New(t)
  11. array := []interface{}{"hello"}
  12. str, err := MarshalToString(array)
  13. should.Nil(err)
  14. should.Equal(`["hello"]`, str)
  15. }
  16. func Test_write_map_of_interface(t *testing.T) {
  17. should := require.New(t)
  18. val := map[string]interface{}{"hello": "world"}
  19. str, err := MarshalToString(val)
  20. should.Nil(err)
  21. should.Equal(`{"hello":"world"}`, str)
  22. }
  23. func Test_write_map_of_interface_in_struct(t *testing.T) {
  24. type TestObject struct {
  25. Field map[string]interface{}
  26. }
  27. should := require.New(t)
  28. val := TestObject{map[string]interface{}{"hello": "world"}}
  29. str, err := MarshalToString(val)
  30. should.Nil(err)
  31. should.Equal(`{"Field":{"hello":"world"}}`, str)
  32. }
  33. func Test_write_map_of_interface_in_struct_with_two_fields(t *testing.T) {
  34. type TestObject struct {
  35. Field map[string]interface{}
  36. Field2 string
  37. }
  38. should := require.New(t)
  39. val := TestObject{map[string]interface{}{"hello": "world"}, ""}
  40. str, err := MarshalToString(val)
  41. should.Nil(err)
  42. should.Contains(str, `"Field":{"hello":"world"}`)
  43. }
  44. type MyInterface interface {
  45. Hello() string
  46. }
  47. type MyString string
  48. func (ms MyString) Hello() string {
  49. return string(ms)
  50. }
  51. func Test_write_map_of_custom_interface(t *testing.T) {
  52. should := require.New(t)
  53. myStr := MyString("world")
  54. should.Equal("world", myStr.Hello())
  55. val := map[string]MyInterface{"hello": myStr}
  56. str, err := MarshalToString(val)
  57. should.Nil(err)
  58. should.Equal(`{"hello":"world"}`, str)
  59. }
  60. func Test_write_interface(t *testing.T) {
  61. should := require.New(t)
  62. var val interface{}
  63. val = "hello"
  64. str, err := MarshalToString(val)
  65. should.Nil(err)
  66. should.Equal(`"hello"`, str)
  67. }
  68. func Test_read_interface(t *testing.T) {
  69. should := require.New(t)
  70. var val interface{}
  71. err := UnmarshalFromString(`"hello"`, &val)
  72. should.Nil(err)
  73. should.Equal("hello", val)
  74. err = UnmarshalFromString(`1e1`, &val)
  75. should.Nil(err)
  76. should.Equal(float64(10), val)
  77. err = UnmarshalFromString(`1.0e1`, &val)
  78. should.Nil(err)
  79. should.Equal(float64(10), val)
  80. err = json.Unmarshal([]byte(`1.0e1`), &val)
  81. should.Nil(err)
  82. should.Equal(float64(10), val)
  83. }
  84. func Test_read_custom_interface(t *testing.T) {
  85. should := require.New(t)
  86. var val MyInterface
  87. RegisterTypeDecoderFunc("jsoniter.MyInterface", func(ptr unsafe.Pointer, iter *Iterator) {
  88. *((*MyInterface)(ptr)) = MyString(iter.ReadString())
  89. })
  90. err := UnmarshalFromString(`"hello"`, &val)
  91. should.Nil(err)
  92. should.Equal("hello", val.Hello())
  93. }
  94. func Test_decode_object_contain_empty_interface(t *testing.T) {
  95. type TestObject struct {
  96. Field interface{}
  97. }
  98. should := require.New(t)
  99. obj := TestObject{}
  100. obj.Field = 1024
  101. should.Nil(UnmarshalFromString(`{"Field": "hello"}`, &obj))
  102. should.Equal("hello", obj.Field)
  103. }
  104. func Test_decode_object_contain_non_empty_interface(t *testing.T) {
  105. type TestObject struct {
  106. Field MyInterface
  107. }
  108. should := require.New(t)
  109. obj := TestObject{}
  110. obj.Field = MyString("abc")
  111. should.Nil(UnmarshalFromString(`{"Field": "hello"}`, &obj))
  112. should.Equal(MyString("hello"), obj.Field)
  113. }
  114. func Test_encode_object_contain_empty_interface(t *testing.T) {
  115. type TestObject struct {
  116. Field interface{}
  117. }
  118. should := require.New(t)
  119. obj := TestObject{}
  120. obj.Field = 1024
  121. str, err := MarshalToString(obj)
  122. should.Nil(err)
  123. should.Equal(`{"Field":1024}`, str)
  124. }
  125. func Test_encode_object_contain_non_empty_interface(t *testing.T) {
  126. type TestObject struct {
  127. Field MyInterface
  128. }
  129. should := require.New(t)
  130. obj := TestObject{}
  131. obj.Field = MyString("hello")
  132. str, err := MarshalToString(obj)
  133. should.Nil(err)
  134. should.Equal(`{"Field":"hello"}`, str)
  135. }
  136. func Test_nil_non_empty_interface(t *testing.T) {
  137. ConfigDefault.(*frozenConfig).cleanEncoders()
  138. ConfigDefault.(*frozenConfig).cleanDecoders()
  139. type TestObject struct {
  140. Field []MyInterface
  141. }
  142. should := require.New(t)
  143. obj := TestObject{}
  144. b := []byte(`{"Field":["AAA"]}`)
  145. should.NotNil(json.Unmarshal(b, &obj))
  146. should.NotNil(Unmarshal(b, &obj))
  147. }
  148. func Test_read_large_number_as_interface(t *testing.T) {
  149. should := require.New(t)
  150. var val interface{}
  151. err := Config{UseNumber: true}.Froze().UnmarshalFromString(`123456789123456789123456789`, &val)
  152. should.Nil(err)
  153. output, err := MarshalToString(val)
  154. should.Nil(err)
  155. should.Equal(`123456789123456789123456789`, output)
  156. }
  157. func Test_nested_one_field_struct(t *testing.T) {
  158. should := require.New(t)
  159. type YetYetAnotherObject struct {
  160. Field string
  161. }
  162. type YetAnotherObject struct {
  163. Field *YetYetAnotherObject
  164. }
  165. type AnotherObject struct {
  166. Field *YetAnotherObject
  167. }
  168. type TestObject struct {
  169. Me *AnotherObject
  170. }
  171. obj := TestObject{&AnotherObject{&YetAnotherObject{&YetYetAnotherObject{"abc"}}}}
  172. str, err := MarshalToString(obj)
  173. should.Nil(err)
  174. should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str)
  175. str, err = MarshalToString(&obj)
  176. should.Nil(err)
  177. should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str)
  178. }
  179. func Test_struct_with_embedded_ptr_with_tag(t *testing.T) {
  180. type O1 struct {
  181. O1F string
  182. }
  183. type Option struct {
  184. O1 *O1
  185. }
  186. type T struct {
  187. Option `json:","`
  188. }
  189. var obj T
  190. should := require.New(t)
  191. output, err := MarshalToString(obj)
  192. should.Nil(err)
  193. should.Equal(`{"O1":null}`, output)
  194. }
  195. func Test_struct_with_one_nil(t *testing.T) {
  196. type TestObject struct {
  197. F *float64
  198. }
  199. var obj TestObject
  200. should := require.New(t)
  201. output, err := MarshalToString(obj)
  202. should.Nil(err)
  203. should.Equal(`{"F":null}`, output)
  204. }
  205. func Test_struct_with_one_nil_embedded(t *testing.T) {
  206. type Parent struct {
  207. Field1 string
  208. Field2 string
  209. }
  210. type TestObject struct {
  211. *Parent
  212. }
  213. obj := TestObject{}
  214. should := require.New(t)
  215. bytes, err := json.Marshal(obj)
  216. should.Nil(err)
  217. should.Equal("{}", string(bytes))
  218. output, err := MarshalToString(obj)
  219. should.Nil(err)
  220. should.Equal(`{}`, output)
  221. }
  222. func Test_struct_with_not_nil_embedded(t *testing.T) {
  223. type Parent struct {
  224. Field0 string
  225. Field1 []string
  226. Field2 map[string]interface{}
  227. }
  228. type TestObject struct {
  229. *Parent
  230. }
  231. should := require.New(t)
  232. var obj TestObject
  233. err := UnmarshalFromString(`{"Field0":"1","Field1":null,"Field2":{"K":"V"}}`, &obj)
  234. should.Nil(err)
  235. should.Nil(obj.Field1)
  236. should.Equal(map[string]interface{}{"K": "V"}, obj.Field2)
  237. should.Equal("1", obj.Field0)
  238. }
  239. func Test_array_with_one_nil_ptr(t *testing.T) {
  240. obj := [1]*float64{nil}
  241. should := require.New(t)
  242. output, err := MarshalToString(obj)
  243. should.Nil(err)
  244. should.Equal(`[null]`, output)
  245. }
  246. func Test_array_with_one_not_nil_ptr(t *testing.T) {
  247. two := float64(2)
  248. obj := [1]*float64{&two}
  249. should := require.New(t)
  250. output, err := MarshalToString(obj)
  251. should.Nil(err)
  252. should.Equal(`[2]`, output)
  253. }
  254. func Test_embedded_array_with_one_nil(t *testing.T) {
  255. type TestObject struct {
  256. Field1 int
  257. Field2 [1]*float64
  258. }
  259. var obj TestObject
  260. should := require.New(t)
  261. output, err := MarshalToString(obj)
  262. should.Nil(err)
  263. should.Contains(output, `"Field2":[null]`)
  264. }
  265. func Test_array_with_nothing(t *testing.T) {
  266. var obj [2]*float64
  267. should := require.New(t)
  268. output, err := MarshalToString(obj)
  269. should.Nil(err)
  270. should.Equal(`[null,null]`, output)
  271. }
  272. func Test_unmarshal_ptr_to_interface(t *testing.T) {
  273. type TestData struct {
  274. Name string `json:"name"`
  275. }
  276. should := require.New(t)
  277. var obj interface{} = &TestData{}
  278. err := json.Unmarshal([]byte(`{"name":"value"}`), &obj)
  279. should.Nil(err)
  280. should.Equal("&{value}", fmt.Sprintf("%v", obj))
  281. obj = interface{}(&TestData{})
  282. err = Unmarshal([]byte(`{"name":"value"}`), &obj)
  283. should.Nil(err)
  284. should.Equal("&{value}", fmt.Sprintf("%v", obj))
  285. }
  286. func Test_nil_out_null_interface(t *testing.T) {
  287. type TestData struct {
  288. Field interface{} `json:"field"`
  289. }
  290. should := require.New(t)
  291. var boolVar bool
  292. obj := TestData{
  293. Field: &boolVar,
  294. }
  295. data1 := []byte(`{"field": true}`)
  296. err := Unmarshal(data1, &obj)
  297. should.NoError(err)
  298. should.Equal(true, *(obj.Field.(*bool)))
  299. data2 := []byte(`{"field": null}`)
  300. err = Unmarshal(data2, &obj)
  301. should.NoError(err)
  302. should.Equal(nil, obj.Field)
  303. // Checking stdlib behavior matches.
  304. obj2 := TestData{
  305. Field: &boolVar,
  306. }
  307. err = json.Unmarshal(data1, &obj2)
  308. should.NoError(err)
  309. should.Equal(true, *(obj2.Field.(*bool)))
  310. err = json.Unmarshal(data2, &obj2)
  311. should.NoError(err)
  312. should.Equal(nil, obj2.Field)
  313. }
  314. func Test_omitempty_nil_interface(t *testing.T) {
  315. type TestData struct {
  316. Field interface{} `json:"field,omitempty"`
  317. }
  318. should := require.New(t)
  319. obj := TestData{
  320. Field: nil,
  321. }
  322. js, err := json.Marshal(obj)
  323. should.NoError(err)
  324. should.Equal("{}", string(js))
  325. str, err := MarshalToString(obj)
  326. should.NoError(err)
  327. should.Equal(string(js), str)
  328. }
  329. func Test_omitempty_nil_nonempty_interface(t *testing.T) {
  330. type TestData struct {
  331. Field MyInterface `json:"field,omitempty"`
  332. }
  333. should := require.New(t)
  334. obj := TestData{
  335. Field: nil,
  336. }
  337. js, err := json.Marshal(obj)
  338. should.NoError(err)
  339. should.Equal("{}", string(js))
  340. str, err := MarshalToString(obj)
  341. should.NoError(err)
  342. should.Equal(string(js), str)
  343. obj.Field = MyString("hello")
  344. err = UnmarshalFromString(`{"field":null}`, &obj)
  345. should.NoError(err)
  346. should.Equal(nil, obj.Field)
  347. }
  348. func Test_marshal_nil_marshaler_interface(t *testing.T) {
  349. type TestData struct {
  350. Field json.Marshaler `json:"field"`
  351. }
  352. should := require.New(t)
  353. obj := TestData{
  354. Field: nil,
  355. }
  356. js, err := json.Marshal(obj)
  357. should.NoError(err)
  358. should.Equal(`{"field":null}`, string(js))
  359. str, err := MarshalToString(obj)
  360. should.NoError(err)
  361. should.Equal(string(js), str)
  362. }
  363. func Test_marshal_nil_nonempty_interface(t *testing.T) {
  364. type TestData struct {
  365. Field MyInterface `json:"field"`
  366. }
  367. should := require.New(t)
  368. obj := TestData{
  369. Field: nil,
  370. }
  371. js, err := json.Marshal(obj)
  372. should.NoError(err)
  373. should.Equal(`{"field":null}`, string(js))
  374. str, err := MarshalToString(obj)
  375. should.NoError(err)
  376. should.Equal(string(js), str)
  377. obj.Field = MyString("hello")
  378. err = Unmarshal(js, &obj)
  379. should.NoError(err)
  380. should.Equal(nil, obj.Field)
  381. }
  382. func Test_overwrite_interface_ptr_value_with_nil(t *testing.T) {
  383. type Wrapper struct {
  384. Payload interface{} `json:"payload,omitempty"`
  385. }
  386. type Payload struct {
  387. Value int `json:"val,omitempty"`
  388. }
  389. should := require.New(t)
  390. payload := &Payload{}
  391. wrapper := &Wrapper{
  392. Payload: &payload,
  393. }
  394. err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
  395. should.Equal(nil, err)
  396. should.Equal(&payload, wrapper.Payload)
  397. should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
  398. err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
  399. should.Equal(nil, err)
  400. should.Equal(&payload, wrapper.Payload)
  401. should.Equal((*Payload)(nil), payload)
  402. payload = &Payload{}
  403. wrapper = &Wrapper{
  404. Payload: &payload,
  405. }
  406. err = Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
  407. should.Equal(nil, err)
  408. should.Equal(&payload, wrapper.Payload)
  409. should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
  410. err = Unmarshal([]byte(`{"payload": null}`), &wrapper)
  411. should.Equal(nil, err)
  412. should.Equal(&payload, wrapper.Payload)
  413. should.Equal((*Payload)(nil), payload)
  414. }
  415. func Test_overwrite_interface_value_with_nil(t *testing.T) {
  416. type Wrapper struct {
  417. Payload interface{} `json:"payload,omitempty"`
  418. }
  419. type Payload struct {
  420. Value int `json:"val,omitempty"`
  421. }
  422. should := require.New(t)
  423. payload := &Payload{}
  424. wrapper := &Wrapper{
  425. Payload: payload,
  426. }
  427. err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
  428. should.Equal(nil, err)
  429. should.Equal(42, (*(wrapper.Payload.(*Payload))).Value)
  430. err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
  431. should.Equal(nil, err)
  432. should.Equal(nil, wrapper.Payload)
  433. should.Equal(42, payload.Value)
  434. payload = &Payload{}
  435. wrapper = &Wrapper{
  436. Payload: payload,
  437. }
  438. err = Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
  439. should.Equal(nil, err)
  440. should.Equal(42, (*(wrapper.Payload.(*Payload))).Value)
  441. err = Unmarshal([]byte(`{"payload": null}`), &wrapper)
  442. should.Equal(nil, err)
  443. should.Equal(nil, wrapper.Payload)
  444. should.Equal(42, payload.Value)
  445. }
  446. func Test_unmarshal_into_nil(t *testing.T) {
  447. type Payload struct {
  448. Value int `json:"val,omitempty"`
  449. }
  450. type Wrapper struct {
  451. Payload interface{} `json:"payload,omitempty"`
  452. }
  453. should := require.New(t)
  454. var payload *Payload
  455. wrapper := &Wrapper{
  456. Payload: payload,
  457. }
  458. err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
  459. should.Nil(err)
  460. should.NotNil(wrapper.Payload)
  461. should.Nil(payload)
  462. err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
  463. should.Nil(err)
  464. should.Nil(wrapper.Payload)
  465. should.Nil(payload)
  466. payload = nil
  467. wrapper = &Wrapper{
  468. Payload: payload,
  469. }
  470. err = Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
  471. should.Nil(err)
  472. should.NotNil(wrapper.Payload)
  473. should.Nil(payload)
  474. err = Unmarshal([]byte(`{"payload": null}`), &wrapper)
  475. should.Nil(err)
  476. should.Nil(wrapper.Payload)
  477. should.Nil(payload)
  478. }