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 }