1package misc_tests
2
3import (
4	"encoding/json"
5	"github.com/json-iterator/go"
6	"github.com/stretchr/testify/require"
7	"io"
8	"testing"
9)
10
11func Test_nil_non_empty_interface(t *testing.T) {
12	type TestObject struct {
13		Field []io.Closer
14	}
15	should := require.New(t)
16	obj := TestObject{}
17	b := []byte(`{"Field":["AAA"]}`)
18	should.NotNil(json.Unmarshal(b, &obj))
19	should.NotNil(jsoniter.Unmarshal(b, &obj))
20}
21
22func Test_nil_out_null_interface(t *testing.T) {
23	type TestData struct {
24		Field interface{} `json:"field"`
25	}
26	should := require.New(t)
27
28	var boolVar bool
29	obj := TestData{
30		Field: &boolVar,
31	}
32
33	data1 := []byte(`{"field": true}`)
34
35	err := jsoniter.Unmarshal(data1, &obj)
36	should.NoError(err)
37	should.Equal(true, *(obj.Field.(*bool)))
38
39	data2 := []byte(`{"field": null}`)
40
41	err = jsoniter.Unmarshal(data2, &obj)
42	should.NoError(err)
43	should.Nil(obj.Field)
44
45	// Checking stdlib behavior matches.
46	obj2 := TestData{
47		Field: &boolVar,
48	}
49
50	err = json.Unmarshal(data1, &obj2)
51	should.NoError(err)
52	should.Equal(true, *(obj2.Field.(*bool)))
53
54	err = json.Unmarshal(data2, &obj2)
55	should.NoError(err)
56	should.Equal(nil, obj2.Field)
57}
58
59func Test_overwrite_interface_ptr_value_with_nil(t *testing.T) {
60	type Wrapper struct {
61		Payload interface{} `json:"payload,omitempty"`
62	}
63	type Payload struct {
64		Value int `json:"val,omitempty"`
65	}
66
67	should := require.New(t)
68
69	payload := &Payload{}
70	wrapper := &Wrapper{
71		Payload: &payload,
72	}
73
74	err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
75	should.NoError(err)
76	should.Equal(&payload, wrapper.Payload)
77	should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
78
79	err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
80	should.NoError(err)
81	should.Equal(&payload, wrapper.Payload)
82	should.Equal((*Payload)(nil), payload)
83
84	payload = &Payload{}
85	wrapper = &Wrapper{
86		Payload: &payload,
87	}
88
89	err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
90	should.Equal(nil, err)
91	should.Equal(&payload, wrapper.Payload)
92	should.Equal(42, (*(wrapper.Payload.(**Payload))).Value)
93
94	err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
95	should.NoError(err)
96	should.Equal(&payload, wrapper.Payload)
97	should.Equal((*Payload)(nil), payload)
98}
99
100func Test_overwrite_interface_value_with_nil(t *testing.T) {
101	type Wrapper struct {
102		Payload interface{} `json:"payload,omitempty"`
103	}
104	type Payload struct {
105		Value int `json:"val,omitempty"`
106	}
107
108	should := require.New(t)
109
110	payload := &Payload{}
111	wrapper := &Wrapper{
112		Payload: payload,
113	}
114
115	err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
116	should.NoError(err)
117	should.Equal(42, wrapper.Payload.(*Payload).Value)
118
119	err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
120	should.NoError(err)
121	should.Equal(nil, wrapper.Payload)
122	should.Equal(42, payload.Value)
123
124	payload = &Payload{}
125	wrapper = &Wrapper{
126		Payload: payload,
127	}
128
129	err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
130	should.Equal(nil, err)
131	should.Equal(42, wrapper.Payload.(*Payload).Value)
132
133	err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
134	should.Equal(nil, err)
135	should.Equal(nil, wrapper.Payload)
136	should.Equal(42, payload.Value)
137}
138
139func Test_unmarshal_into_nil(t *testing.T) {
140	type Payload struct {
141		Value int `json:"val,omitempty"`
142	}
143	type Wrapper struct {
144		Payload interface{} `json:"payload,omitempty"`
145	}
146
147	should := require.New(t)
148
149	var payload *Payload
150	wrapper := &Wrapper{
151		Payload: payload,
152	}
153
154	err := json.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
155	should.NoError(err)
156	should.NotNil(wrapper.Payload)
157	should.Nil(payload)
158
159	err = json.Unmarshal([]byte(`{"payload": null}`), &wrapper)
160	should.NoError(err)
161	should.Nil(wrapper.Payload)
162	should.Nil(payload)
163
164	payload = nil
165	wrapper = &Wrapper{
166		Payload: payload,
167	}
168
169	err = jsoniter.Unmarshal([]byte(`{"payload": {"val": 42}}`), &wrapper)
170	should.NoError(err)
171	should.NotNil(wrapper.Payload)
172	should.Nil(payload)
173
174	err = jsoniter.Unmarshal([]byte(`{"payload": null}`), &wrapper)
175	should.NoError(err)
176	should.Nil(wrapper.Payload)
177	should.Nil(payload)
178}
179