github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/jsoni/misc_tests/jsoniter_interface_test.go (about)

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