jsoniter_interface_test.go 13 KB

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