decode_interface_test.go (13196B)
1 package gojay 2 3 import ( 4 "encoding/json" 5 "strings" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestDecodeInterfaceBasic(t *testing.T) { 12 testCases := []struct { 13 name string 14 json string 15 expectedResult interface{} 16 err bool 17 errType interface{} 18 skipCheckResult bool 19 }{ 20 { 21 name: "array", 22 json: `[1,2,3]`, 23 expectedResult: []interface{}([]interface{}{float64(1), float64(2), float64(3)}), 24 err: false, 25 }, 26 { 27 name: "object", 28 json: `{"testStr": "hello world!"}`, 29 expectedResult: map[string]interface{}(map[string]interface{}{"testStr": "hello world!"}), 30 err: false, 31 }, 32 { 33 name: "string", 34 json: `"hola amigos!"`, 35 expectedResult: interface{}("hola amigos!"), 36 err: false, 37 }, 38 { 39 name: "bool-true", 40 json: `true`, 41 expectedResult: interface{}(true), 42 err: false, 43 }, 44 { 45 name: "bool-false", 46 json: `false`, 47 expectedResult: interface{}(false), 48 err: false, 49 }, 50 { 51 name: "null", 52 json: `null`, 53 expectedResult: interface{}(nil), 54 err: false, 55 }, 56 { 57 name: "number", 58 json: `1234`, 59 expectedResult: interface{}(float64(1234)), 60 err: false, 61 }, 62 { 63 name: "array-error", 64 json: `["h""o","l","a"]`, 65 err: true, 66 errType: &json.SyntaxError{}, 67 skipCheckResult: true, 68 }, 69 { 70 name: "object-error", 71 json: `{"testStr" "hello world!"}`, 72 err: true, 73 errType: &json.SyntaxError{}, 74 skipCheckResult: true, 75 }, 76 { 77 name: "string-error", 78 json: `"hola amigos!`, 79 err: true, 80 errType: InvalidJSONError(""), 81 skipCheckResult: true, 82 }, 83 { 84 name: "bool-true-error", 85 json: `truee`, 86 err: true, 87 errType: InvalidJSONError(""), 88 skipCheckResult: true, 89 }, 90 { 91 name: "bool-false-error", 92 json: `fase`, 93 expectedResult: interface{}(false), 94 err: true, 95 errType: InvalidJSONError(""), 96 skipCheckResult: true, 97 }, 98 { 99 name: "null-error", 100 json: `nulllll`, 101 err: true, 102 errType: InvalidJSONError(""), 103 skipCheckResult: true, 104 }, 105 { 106 name: "number-error", 107 json: `1234"`, 108 err: true, 109 errType: InvalidJSONError(""), 110 skipCheckResult: true, 111 }, 112 { 113 name: "unknown-error", 114 json: `?`, 115 err: true, 116 errType: InvalidJSONError(""), 117 skipCheckResult: true, 118 }, 119 { 120 name: "empty-json-error", 121 json: ``, 122 err: true, 123 errType: InvalidJSONError(""), 124 skipCheckResult: true, 125 }, 126 } 127 128 for _, testCase := range testCases { 129 t.Run("DecodeInterface()"+testCase.name, func(t *testing.T) { 130 var i interface{} 131 dec := BorrowDecoder(strings.NewReader(testCase.json)) 132 defer dec.Release() 133 err := dec.DecodeInterface(&i) 134 if testCase.err { 135 t.Log(err) 136 assert.NotNil(t, err, "err should not be nil") 137 if testCase.errType != nil { 138 assert.IsType(t, testCase.errType, err, "err should be of the given type") 139 } 140 return 141 } 142 assert.Nil(t, err, "err should be nil") 143 if !testCase.skipCheckResult { 144 assert.Equal(t, testCase.expectedResult, i, "value at given index should be the same as expected results") 145 } 146 }) 147 } 148 149 for _, testCase := range testCases { 150 t.Run("Decode()"+testCase.name, func(t *testing.T) { 151 var i interface{} 152 dec := BorrowDecoder(strings.NewReader(testCase.json)) 153 defer dec.Release() 154 err := dec.Decode(&i) 155 if testCase.err { 156 t.Log(err) 157 assert.NotNil(t, err, "err should not be nil") 158 if testCase.errType != nil { 159 assert.IsType(t, testCase.errType, err, "err should be of the given type") 160 } 161 return 162 } 163 assert.Nil(t, err, "err should be nil") 164 if !testCase.skipCheckResult { 165 assert.Equal(t, testCase.expectedResult, i, "value at given index should be the same as expected results") 166 } 167 }) 168 } 169 } 170 171 func TestDecodeInterfaceAsInterface(t *testing.T) { 172 testCases := []struct { 173 name string 174 json string 175 expectedResult interface{} 176 err bool 177 errType interface{} 178 skipCheckResult bool 179 }{ 180 { 181 name: "basic-array", 182 json: `{ 183 "testStr": "hola", 184 "testInterface": ["h","o","l","a"] 185 }`, 186 expectedResult: map[string]interface{}( 187 map[string]interface{}{ 188 "testStr": "hola", 189 "testInterface": []interface{}{"h", "o", "l", "a"}, 190 }), 191 err: false, 192 }, 193 { 194 name: "basic-string", 195 json: `{ 196 "testInterface": "漢字" 197 }`, 198 expectedResult: map[string]interface{}( 199 map[string]interface{}{ 200 "testInterface": "漢字", 201 }), 202 err: false, 203 }, 204 { 205 name: "basic-error", 206 json: `{ 207 "testInterface": ["a""d","i","o","s"] 208 }`, 209 err: true, 210 errType: &json.SyntaxError{}, 211 skipCheckResult: true, 212 }, 213 { 214 name: "basic-interface", 215 json: `{ 216 "testInterface": { 217 "string": "prost" 218 } 219 }`, 220 expectedResult: map[string]interface{}( 221 map[string]interface{}{ 222 "testInterface": map[string]interface{}{"string": "prost"}, 223 }), 224 err: false, 225 }, 226 { 227 name: "complex-interface", 228 json: `{ 229 "testInterface": { 230 "number": 1988, 231 "string": "prost", 232 "array": ["h","o","l","a"], 233 "object": { 234 "k": "v", 235 "a": [1,2,3] 236 }, 237 "array-of-objects": [ 238 {"k": "v"}, 239 {"a": "b"} 240 ] 241 } 242 }`, 243 expectedResult: map[string]interface{}( 244 map[string]interface{}{ 245 "testInterface": map[string]interface{}{ 246 "array-of-objects": []interface{}{ 247 map[string]interface{}{"k": "v"}, 248 map[string]interface{}{"a": "b"}, 249 }, 250 "number": float64(1988), 251 "string": "prost", 252 "array": []interface{}{"h", "o", "l", "a"}, 253 "object": map[string]interface{}{ 254 "k": "v", 255 "a": []interface{}{float64(1), float64(2), float64(3)}, 256 }, 257 }, 258 }), 259 err: false, 260 }, 261 } 262 263 for _, testCase := range testCases { 264 t.Run("Decode()"+testCase.name, func(t *testing.T) { 265 var s interface{} 266 dec := BorrowDecoder(strings.NewReader(testCase.json)) 267 defer dec.Release() 268 err := dec.Decode(&s) 269 if testCase.err { 270 t.Log(err) 271 assert.NotNil(t, err, "err should not be nil") 272 if testCase.errType != nil { 273 assert.IsType(t, testCase.errType, err, "err should be of the given type") 274 } 275 return 276 } 277 assert.Nil(t, err, "err should be nil") 278 if !testCase.skipCheckResult { 279 assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results") 280 } 281 }) 282 } 283 284 for _, testCase := range testCases { 285 t.Run("DecodeInterface()"+testCase.name, func(t *testing.T) { 286 var s interface{} 287 dec := BorrowDecoder(strings.NewReader(testCase.json)) 288 defer dec.Release() 289 err := dec.DecodeInterface(&s) 290 if testCase.err { 291 t.Log(err) 292 assert.NotNil(t, err, "err should not be nil") 293 if testCase.errType != nil { 294 assert.IsType(t, testCase.errType, err, "err should be of the given type") 295 } 296 return 297 } 298 assert.Nil(t, err, "err should be nil") 299 if !testCase.skipCheckResult { 300 assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results") 301 } 302 }) 303 } 304 } 305 306 func TestDecodeAsTestObject(t *testing.T) { 307 testCases := []struct { 308 name string 309 json string 310 expectedResult testObject 311 err bool 312 errType interface{} 313 skipCheckResult bool 314 }{ 315 { 316 name: "basic-array", 317 json: `{ 318 "testStr": "hola", 319 "testInterface": ["h","o","l","a"] 320 }`, 321 expectedResult: testObject{ 322 testStr: "hola", 323 testInterface: []interface{}([]interface{}{"h", "o", "l", "a"}), 324 }, 325 err: false, 326 }, 327 { 328 name: "basic-string", 329 json: `{ 330 "testInterface": "漢字" 331 }`, 332 expectedResult: testObject{ 333 testInterface: interface{}("漢字"), 334 }, 335 err: false, 336 }, 337 { 338 name: "basic-error", 339 json: `{ 340 "testInterface": ["a""d","i","o","s"] 341 }`, 342 err: true, 343 errType: &json.SyntaxError{}, 344 skipCheckResult: true, 345 }, 346 { 347 name: "mull-interface", 348 json: `{ 349 "testInterface": null, 350 "testStr": "adios" 351 }`, 352 expectedResult: testObject{ 353 testInterface: interface{}(nil), 354 testStr: "adios", 355 }, 356 err: false, 357 }, 358 { 359 name: "basic-interface", 360 json: `{ 361 "testInterface": { 362 "string": "prost" 363 }, 364 }`, 365 expectedResult: testObject{ 366 testInterface: map[string]interface{}{"string": "prost"}, 367 }, 368 err: false, 369 }, 370 { 371 name: "complex-interface", 372 json: `{ 373 "testInterface": { 374 "number": 1988, 375 "string": "prost", 376 "array": ["h","o","l","a"], 377 "object": { 378 "k": "v", 379 "a": [1,2,3] 380 }, 381 "array-of-objects": [ 382 {"k": "v"}, 383 {"a": "b"} 384 ] 385 }, 386 }`, 387 expectedResult: testObject{ 388 testInterface: map[string]interface{}{ 389 "array-of-objects": []interface{}{ 390 map[string]interface{}{"k": "v"}, 391 map[string]interface{}{"a": "b"}, 392 }, 393 "number": float64(1988), 394 "string": "prost", 395 "array": []interface{}{"h", "o", "l", "a"}, 396 "object": map[string]interface{}{ 397 "k": "v", 398 "a": []interface{}{float64(1), float64(2), float64(3)}, 399 }, 400 }, 401 }, 402 err: false, 403 }, 404 } 405 for _, testCase := range testCases { 406 t.Run(testCase.name, func(t *testing.T) { 407 s := testObject{} 408 dec := BorrowDecoder(strings.NewReader(testCase.json)) 409 defer dec.Release() 410 err := dec.Decode(&s) 411 if testCase.err { 412 t.Log(err) 413 assert.NotNil(t, err, "err should not be nil") 414 if testCase.errType != nil { 415 assert.IsType(t, testCase.errType, err, "err should be of the given type") 416 } 417 return 418 } 419 assert.Nil(t, err, "err should be nil") 420 if !testCase.skipCheckResult { 421 assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results") 422 } 423 }) 424 } 425 } 426 427 func TestUnmarshalInterface(t *testing.T) { 428 json := []byte(`{ 429 "testInterface": { 430 "number": 1988, 431 "null": null, 432 "string": "prost", 433 "array": ["h","o","l","a"], 434 "object": { 435 "k": "v", 436 "a": [1,2,3] 437 }, 438 "array-of-objects": [ 439 {"k": "v"}, 440 {"a": "b"} 441 ] 442 } 443 }`) 444 v := &testObject{} 445 err := Unmarshal(json, v) 446 assert.Nil(t, err, "Err must be nil") 447 expectedInterface := map[string]interface{}{ 448 "array-of-objects": []interface{}{ 449 map[string]interface{}{"k": "v"}, 450 map[string]interface{}{"a": "b"}, 451 }, 452 "number": float64(1988), 453 "string": "prost", 454 "null": interface{}(nil), 455 "array": []interface{}{"h", "o", "l", "a"}, 456 "object": map[string]interface{}{ 457 "k": "v", 458 "a": []interface{}{float64(1), float64(2), float64(3)}, 459 }, 460 } 461 assert.Equal(t, expectedInterface, v.testInterface, "v.testInterface must be equal to the expected one") 462 } 463 464 func TestUnmarshalInterfaceError(t *testing.T) { 465 testCases := []struct { 466 name string 467 json []byte 468 }{ 469 { 470 name: "basic", 471 json: []byte(`{"testInterface": {"number": 1bc4}}`), 472 }, 473 { 474 name: "syntax", 475 json: []byte(`{ 476 "testInterface": { 477 "array?": [1,"a", ?] 478 } 479 }`), 480 }, 481 { 482 name: "complex", 483 json: []byte(`{ 484 "testInterface": { 485 "number": 1988, 486 "string": "prost", 487 "array": ["h""o","l","a"], 488 "object": { 489 "k": "v", 490 "a": [1,2,3] 491 }, 492 "array-of-objects": [ 493 {"k": "v"}, 494 {"a": "b"} 495 ] 496 } 497 }`), 498 }, 499 } 500 for _, testCase := range testCases { 501 t.Run(testCase.name, func(t *testing.T) { 502 v := &testObject{} 503 err := Unmarshal(testCase.json, v) 504 assert.NotNil(t, err, "Err must be not nil") 505 t.Log(err) 506 assert.IsType(t, &json.SyntaxError{}, err, "err should be a json.SyntaxError{}") 507 }) 508 } 509 } 510 511 func TestDecodeInterfacePoolError(t *testing.T) { 512 result := interface{}(1) 513 dec := NewDecoder(nil) 514 dec.Release() 515 defer func() { 516 err := recover() 517 assert.NotNil(t, err, "err shouldnt be nil") 518 assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError") 519 }() 520 _ = dec.DecodeInterface(&result) 521 assert.True(t, false, "should not be called as decoder should have panicked") 522 } 523 524 func TestDecodeNull(t *testing.T) { 525 var i interface{} 526 dec := BorrowDecoder(strings.NewReader("null")) 527 defer dec.Release() 528 err := dec.DecodeInterface(&i) 529 assert.Nil(t, err, "err should be nil") 530 assert.Equal(t, interface{}(nil), i, "value at given index should be the same as expected results") 531 }