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