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

     1  package test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"io"
     8  	"testing"
     9  
    10  	"github.com/bingoohuang/gg/pkg/jsoni"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func Test_missing_object_end(t *testing.T) {
    16  	should := require.New(t)
    17  	type TestObject struct {
    18  		Metric string                 `json:"metric"`
    19  		Tags   map[string]interface{} `json:"tags"`
    20  	}
    21  	obj := TestObject{}
    22  	should.NotNil(jsoni.UnmarshalFromString(`{"metric": "sys.777","tags": {"a":"123"}`, &obj))
    23  }
    24  
    25  func Test_missing_array_end(t *testing.T) {
    26  	should := require.New(t)
    27  	should.NotNil(jsoni.UnmarshalFromString(`[1,2,3`, &[]int{}))
    28  }
    29  
    30  func Test_invalid_any(t *testing.T) {
    31  	should := require.New(t)
    32  	any := jsoni.Get([]byte("[]"))
    33  	should.Equal(jsoni.InvalidValue, any.Get(0.3).ValueType())
    34  	// is nil correct ?
    35  	should.Equal(nil, any.Get(0.3).GetInterface(nil))
    36  
    37  	any = any.Get(0.3)
    38  	should.Equal(false, any.ToBool())
    39  	should.Equal(int(0), any.ToInt())
    40  	should.Equal(int32(0), any.ToInt32())
    41  	should.Equal(int64(0), any.ToInt64())
    42  	should.Equal(uint(0), any.ToUint())
    43  	should.Equal(uint32(0), any.ToUint32())
    44  	should.Equal(uint64(0), any.ToUint64())
    45  	should.Equal(float32(0), any.ToFloat32())
    46  	should.Equal(float64(0), any.ToFloat64())
    47  	should.Equal("", any.ToString())
    48  
    49  	should.Equal(jsoni.InvalidValue, any.Get(0.1).Get(1).ValueType())
    50  }
    51  
    52  func Test_invalid_struct_input(t *testing.T) {
    53  	should := require.New(t)
    54  	type TestObject struct{}
    55  	input := []byte{54, 141, 30}
    56  	obj := TestObject{}
    57  	should.NotNil(jsoni.Unmarshal(input, &obj))
    58  }
    59  
    60  func Test_invalid_slice_input(t *testing.T) {
    61  	should := require.New(t)
    62  	type TestObject struct{}
    63  	input := []byte{93}
    64  	obj := []string{}
    65  	should.NotNil(jsoni.Unmarshal(input, &obj))
    66  }
    67  
    68  func Test_invalid_array_input(t *testing.T) {
    69  	should := require.New(t)
    70  	type TestObject struct{}
    71  	input := []byte{93}
    72  	obj := [0]string{}
    73  	should.NotNil(jsoni.Unmarshal(input, &obj))
    74  }
    75  
    76  func Test_invalid_float(t *testing.T) {
    77  	inputs := []string{
    78  		`1.e1`, // dot without following digit
    79  		`1.`,   // dot can not be the last char
    80  		``,     // empty number
    81  		`01`,   // extra leading zero
    82  		`-`,    // negative without digit
    83  		`--`,   // double negative
    84  		`--2`,  // double negative
    85  	}
    86  	for _, input := range inputs {
    87  		t.Run(input, func(t *testing.T) {
    88  			should := require.New(t)
    89  			iter := jsoni.ParseString(jsoni.ConfigDefault, input+",")
    90  			iter.Skip()
    91  			should.NotEqual(io.EOF, iter.Error)
    92  			should.NotNil(iter.Error)
    93  			v := float64(0)
    94  			should.NotNil(json.Unmarshal([]byte(input), &v))
    95  			iter = jsoni.ParseString(jsoni.ConfigDefault, input+",")
    96  			iter.ReadFloat64()
    97  			should.NotEqual(io.EOF, iter.Error)
    98  			should.NotNil(iter.Error)
    99  			iter = jsoni.ParseString(jsoni.ConfigDefault, input+",")
   100  			iter.ReadFloat32()
   101  			should.NotEqual(io.EOF, iter.Error)
   102  			should.NotNil(iter.Error)
   103  		})
   104  	}
   105  }
   106  
   107  func Test_chan(t *testing.T) {
   108  	type TestObject struct {
   109  		MyChan  chan bool
   110  		MyField int
   111  	}
   112  
   113  	obj := TestObject{}
   114  
   115  	t.Run("Encode channel", func(t *testing.T) {
   116  		should := require.New(t)
   117  		str, err := jsoni.Marshal(obj)
   118  		should.NotNil(err)
   119  		should.Nil(str)
   120  	})
   121  
   122  	t.Run("Encode channel using compatible configuration", func(t *testing.T) {
   123  		should := require.New(t)
   124  		str, err := jsoni.ConfigCompatibleWithStandardLibrary.Marshal(context.Background(), obj)
   125  		should.NotNil(err)
   126  		should.Nil(str)
   127  	})
   128  }
   129  
   130  func Test_invalid_in_map(t *testing.T) {
   131  	testMap := map[string]interface{}{"chan": make(chan interface{})}
   132  
   133  	t.Run("Encode map with invalid content", func(t *testing.T) {
   134  		should := require.New(t)
   135  		str, err := jsoni.Marshal(testMap)
   136  		should.NotNil(err)
   137  		should.Nil(str)
   138  	})
   139  
   140  	t.Run("Encode map with invalid content using compatible configuration", func(t *testing.T) {
   141  		should := require.New(t)
   142  		str, err := jsoni.ConfigCompatibleWithStandardLibrary.Marshal(context.Background(), testMap)
   143  		should.NotNil(err)
   144  		should.Nil(str)
   145  	})
   146  }
   147  
   148  func Test_invalid_number(t *testing.T) {
   149  	type Message struct {
   150  		Number int `json:"number"`
   151  	}
   152  	obj := Message{}
   153  	ctx := context.Background()
   154  	decoder := jsoni.ConfigCompatibleWithStandardLibrary.NewDecoder(bytes.NewBufferString(`{"number":"5"}`))
   155  	err := decoder.Decode(ctx, &obj)
   156  	invalidStr := err.Error()
   157  	result, err := jsoni.ConfigCompatibleWithStandardLibrary.Marshal(ctx, invalidStr)
   158  	should := require.New(t)
   159  	should.Nil(err)
   160  	result2, err := json.Marshal(invalidStr)
   161  	should.Nil(err)
   162  	should.Equal(string(result2), string(result))
   163  }
   164  
   165  func Test_valid(t *testing.T) {
   166  	should := require.New(t)
   167  	should.True(jsoni.Valid([]byte(`{}`)))
   168  	should.True(jsoni.Valid([]byte(`[]`)))
   169  	should.False(jsoni.Valid([]byte(`{`)))
   170  }
   171  
   172  func Test_nil_pointer(t *testing.T) {
   173  	should := require.New(t)
   174  	data := []byte(`{"A":0}`)
   175  	type T struct {
   176  		X int
   177  	}
   178  	var obj *T
   179  	err := jsoni.Unmarshal(data, obj)
   180  	should.NotNil(err)
   181  }
   182  
   183  func Test_func_pointer_type(t *testing.T) {
   184  	type TestObject2 struct {
   185  		F func()
   186  	}
   187  	type TestObject1 struct {
   188  		Obj *TestObject2
   189  	}
   190  	t.Run("encode null is valid", func(t *testing.T) {
   191  		should := require.New(t)
   192  		output, err := json.Marshal(TestObject1{})
   193  		should.Nil(err)
   194  		should.Equal(`{"Obj":null}`, string(output))
   195  		output, err = jsoni.Marshal(TestObject1{})
   196  		should.Nil(err)
   197  		should.Equal(`{"Obj":null}`, string(output))
   198  	})
   199  	t.Run("encode not null is invalid", func(t *testing.T) {
   200  		should := require.New(t)
   201  		_, err := json.Marshal(TestObject1{Obj: &TestObject2{}})
   202  		should.NotNil(err)
   203  		_, err = jsoni.Marshal(TestObject1{Obj: &TestObject2{}})
   204  		should.NotNil(err)
   205  	})
   206  	t.Run("decode null is valid", func(t *testing.T) {
   207  		should := require.New(t)
   208  		var obj TestObject1
   209  		should.Nil(json.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
   210  		should.Nil(jsoni.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
   211  	})
   212  	t.Run("decode not null is invalid", func(t *testing.T) {
   213  		should := require.New(t)
   214  		var obj TestObject1
   215  		should.NotNil(json.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
   216  		should.NotNil(jsoni.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
   217  	})
   218  }
   219  
   220  func TestEOF(t *testing.T) {
   221  	var s string
   222  	err := jsoni.ConfigCompatibleWithStandardLibrary.NewDecoder(&bytes.Buffer{}).Decode(context.Background(), &s)
   223  	assert.Equal(t, io.EOF, err)
   224  }
   225  
   226  func TestDecodeErrorType(t *testing.T) {
   227  	should := require.New(t)
   228  	var err error
   229  	should.Nil(jsoni.Unmarshal([]byte("null"), &err))
   230  	should.NotNil(jsoni.Unmarshal([]byte("123"), &err))
   231  }
   232  
   233  func Test_decode_slash(t *testing.T) {
   234  	should := require.New(t)
   235  	var obj interface{}
   236  	should.NotNil(json.Unmarshal([]byte("\\"), &obj))
   237  	should.NotNil(jsoni.UnmarshalFromString("\\", &obj))
   238  }
   239  
   240  func Test_NilInput(t *testing.T) {
   241  	var jb []byte // nil
   242  	var out string
   243  	err := jsoni.Unmarshal(jb, &out)
   244  	if err == nil {
   245  		t.Errorf("Expected error")
   246  	}
   247  }
   248  
   249  func Test_EmptyInput(t *testing.T) {
   250  	jb := []byte("")
   251  	var out string
   252  	err := jsoni.Unmarshal(jb, &out)
   253  	if err == nil {
   254  		t.Errorf("Expected error")
   255  	}
   256  }
   257  
   258  type Foo struct {
   259  	A jsoni.Any
   260  }
   261  
   262  func Test_nil_any(t *testing.T) {
   263  	should := require.New(t)
   264  	data, _ := jsoni.Marshal(&Foo{})
   265  	should.Equal(`{"A":null}`, string(data))
   266  }