decode_object_test.go (48082B)
1 package gojay 2 3 import ( 4 "fmt" 5 "io" 6 "reflect" 7 "strings" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func makePointer(v interface{}) interface{} { 14 var ptr = reflect.New(reflect.TypeOf(v)) 15 ptr.Elem().Set(reflect.ValueOf(v)) 16 return ptr.Interface() 17 } 18 19 func TestDecodeObjectBasic(t *testing.T) { 20 testCases := []struct { 21 name string 22 json string 23 expectedResult testObject 24 err bool 25 errType interface{} 26 skipCheckResult bool 27 }{ 28 { 29 name: "basic", 30 json: `{ 31 "testStr": "hello world!", 32 "testStrNull": "hello world!", 33 "testInt": 4535, 34 "testIntNull": 4535, 35 "testBool": true, 36 "testBoolNull": true, 37 "testFloat32": 2.345, 38 "testFloat32Null": 2.345, 39 "testFloat64": 123.677, 40 "testFloat64Null": 123.677, 41 "testInt8": 23, 42 "testInt8Null": 23, 43 "testInt16": 1245, 44 "testInt16Null": 1245, 45 "testInt32": 456778, 46 "testInt32Null": 456778, 47 "testInt64": 1446685358, 48 "testInt64Null": 1446685358, 49 "testUint8": 255, 50 "testUint8Null": 255, 51 "testUint16": 3455, 52 "testUint16Null": 3455, 53 "testUint32": 343443, 54 "testUint32Null": 343443, 55 "testUint64": 545665757, 56 "testUint64Null": 545665757, 57 "testSubObjectNull": { 58 "testStr": "1" 59 } 60 }`, 61 expectedResult: testObject{ 62 testStr: "hello world!", 63 testStrNull: makePointer("hello world!").(*string), 64 testInt: 4535, 65 testIntNull: makePointer(4535).(*int), 66 testBool: true, 67 testBoolNull: makePointer(true).(*bool), 68 testFloat32: 2.345, 69 testFloat32Null: makePointer(float32(2.345)).(*float32), 70 testFloat64: 123.677, 71 testFloat64Null: makePointer(float64(123.677)).(*float64), 72 testInt8: 23, 73 testInt8Null: makePointer(int8(23)).(*int8), 74 testInt16: 1245, 75 testInt16Null: makePointer(int16(1245)).(*int16), 76 testInt32: 456778, 77 testInt32Null: makePointer(int32(456778)).(*int32), 78 testInt64: 1446685358, 79 testInt64Null: makePointer(int64(1446685358)).(*int64), 80 testUint8: 255, 81 testUint8Null: makePointer(uint8(255)).(*uint8), 82 testUint16: 3455, 83 testUint16Null: makePointer(uint16(3455)).(*uint16), 84 testUint32: 343443, 85 testUint32Null: makePointer(uint32(343443)).(*uint32), 86 testUint64: 545665757, 87 testUint64Null: makePointer(uint64(545665757)).(*uint64), 88 }, 89 err: false, 90 }, 91 { 92 name: "basic-with-exponent", 93 json: `{ 94 "testStr": "hello world!", 95 "testInt": 3e3, 96 "testBool": true, 97 "testFloat32": 2.345, 98 "testFloat64": 123.677, 99 "testInt8": 23, 100 "testInt16": 1245, 101 "testInt32": 456778, 102 "testInt64": 1446685358, 103 "testUint8": 255, 104 "testUint16": 3455, 105 "testUint32": 343443, 106 "testUint64": 545665757 107 }`, 108 expectedResult: testObject{ 109 testStr: "hello world!", 110 testInt: 3000, 111 testBool: true, 112 testFloat32: 2.345, 113 testFloat64: 123.677, 114 testInt8: 23, 115 testInt16: 1245, 116 testInt32: 456778, 117 testInt64: 1446685358, 118 testUint8: 255, 119 testUint16: 3455, 120 testUint32: 343443, 121 testUint64: 545665757, 122 }, 123 err: false, 124 }, 125 { 126 name: "basic-with-exponent3", 127 json: `{ 128 "testStr": "hello world!", 129 "testInt": 3e-3, 130 "testBool": true, 131 "testFloat32": 2.345, 132 "testFloat64": 12e-3, 133 "testInt8": 23, 134 "testInt16": 1245, 135 "testInt32": 456778, 136 "testInt64": 1446685358, 137 "testUint8": 255, 138 "testUint16": 3455, 139 "testUint32": 343443, 140 "testUint64": 545665757 141 }`, 142 expectedResult: testObject{ 143 testStr: "hello world!", 144 testInt: 0, 145 testBool: true, 146 testFloat32: 2.345, 147 testFloat64: 0.012, 148 testInt8: 23, 149 testInt16: 1245, 150 testInt32: 456778, 151 testInt64: 1446685358, 152 testUint8: 255, 153 testUint16: 3455, 154 testUint32: 343443, 155 testUint64: 545665757, 156 }, 157 err: false, 158 }, 159 { 160 name: "basic-err-invalid-type", 161 json: `1`, 162 expectedResult: testObject{}, 163 err: true, 164 errType: InvalidUnmarshalError(""), 165 }, 166 { 167 name: "basic-err-invalid-json", 168 json: `hello`, 169 expectedResult: testObject{}, 170 err: true, 171 errType: InvalidJSONError(""), 172 }, 173 { 174 name: "basic-err-invalid-json", 175 json: `nall`, 176 expectedResult: testObject{}, 177 err: true, 178 errType: InvalidJSONError(""), 179 }, 180 { 181 name: "basic-err-invalid-type", 182 json: ``, 183 expectedResult: testObject{}, 184 err: true, 185 errType: InvalidJSONError(""), 186 }, 187 { 188 name: "basic-err", 189 json: `{ 190 "testStr": "hello world!", 191 "testInt": 453q5, 192 "testBool": trae, 193 "testFloat32": 2q.345, 194 "testFloat64": 12x3.677, 195 "testInt8": 2s3, 196 "testInt16": 1245, 197 "testInt32": 4567q78, 198 "testInt64": 14466e85358, 199 "testUint8": 2s55, 200 "testUint16": 345i5, 201 "testUint32": 343q443, 202 "testUint64": 5456657z57 203 }`, 204 expectedResult: testObject{}, 205 err: true, 206 }, 207 { 208 name: "basic-err2", 209 json: `{ 210 "testStr": "hello world!", 211 "testInt": 4535, 212 "testBool": true, 213 "testFloat32": 2.345, 214 "testFloat64": 123.677, 215 "testInt8": 23, 216 "testInt16": 1245, 217 "testInt32": 4567x78, 218 "testInt64": 1446685358, 219 "testUint8": 255, 220 "testUint16": 3455, 221 "testUint32": 343443, 222 "testUint64": 545665757 223 }`, 224 expectedResult: testObject{}, 225 err: true, 226 }, 227 { 228 name: "basic-err-float32", 229 json: `{ 230 "testStr": "hello world!", 231 "testInt": 4535, 232 "testBool": true, 233 "testFloat32": 2q.345, 234 "testFloat64": 123.677, 235 "testInt8": 23, 236 "testInt16": 1245, 237 "testInt32": 456778, 238 "testInt64": 1446685358, 239 "testUint8": 255, 240 "testUint16": 3455, 241 "testUint32": 343443, 242 "testUint64": 545665757 243 }`, 244 expectedResult: testObject{}, 245 err: true, 246 }, 247 { 248 name: "basic-err-float64", 249 json: `{ 250 "testStr": "hello world!", 251 "testInt": 4535, 252 "testBool": true, 253 "testFloat32": 2.345, 254 "testFloat64": 1x23.677, 255 "testInt8": 23, 256 "testInt16": 1245, 257 "testInt32": 456778, 258 "testInt64": 1446685358, 259 "testUint8": 255, 260 "testUint16": 3455, 261 "testUint32": 343443, 262 "testUint64": 545665757 263 }`, 264 expectedResult: testObject{}, 265 err: true, 266 }, 267 { 268 name: "basic-err3", 269 json: `{ 270 "testStr": "hello world!", 271 "testInt": 4535, 272 "testBool": true, 273 "testFloat32": 2.345, 274 "testFloat64": 123.677, 275 "testInt8": 2q3, 276 "testInt16": 1245, 277 "testInt32": 456778, 278 "testInt64": 1446685358, 279 "testUint8": 255, 280 "testUint16": 3455, 281 "testUint32": 343443, 282 "testUint64": 545665757 283 }`, 284 expectedResult: testObject{}, 285 err: true, 286 }, 287 { 288 name: "basic-err-int16", 289 json: `{ 290 "testStr": "hello world!", 291 "testInt": 4535, 292 "testBool": true, 293 "testFloat32": 2.345, 294 "testFloat64": 123.677, 295 "testInt8": 23, 296 "testInt16": 1x245, 297 "testInt32": 456778, 298 "testInt64": 1446685358, 299 "testUint8": 255, 300 "testUint16": 3455, 301 "testUint32": 343443, 302 "testUint64": 545665757 303 }`, 304 expectedResult: testObject{}, 305 err: true, 306 }, 307 { 308 name: "basic-err-int64", 309 json: `{ 310 "testStr": "hello world!", 311 "testInt": 4535, 312 "testBool": true, 313 "testFloat32": 2.345, 314 "testFloat64": 123.677, 315 "testInt8": 23, 316 "testInt16": 1245, 317 "testInt32": 456778, 318 "testInt64": 1446q685358, 319 "testUint8": 255, 320 "testUint16": 3455, 321 "testUint32": 343443, 322 "testUint64": 545665757 323 }`, 324 expectedResult: testObject{}, 325 err: true, 326 }, 327 { 328 name: "basic-err-uint8", 329 json: `{ 330 "testStr": "hello world!", 331 "testInt": 4535, 332 "testBool": true, 333 "testFloat32": 2.345, 334 "testFloat64": 123.677, 335 "testInt8": 23, 336 "testInt16": 1245, 337 "testInt32": 456778, 338 "testInt64": 1446685358, 339 "testUint8": 2x55, 340 "testUint16": 3455, 341 "testUint32": 343443, 342 "testUint64": 545665757 343 }`, 344 expectedResult: testObject{}, 345 err: true, 346 }, 347 { 348 name: "basic-err-uint16", 349 json: `{ 350 "testStr": "hello world!", 351 "testInt": 4535, 352 "testBool": true, 353 "testFloat32": 2.345, 354 "testFloat64": 123.677, 355 "testInt8": 23, 356 "testInt16": 1245, 357 "testInt32": 456778, 358 "testInt64": 1446685358, 359 "testUint8": 255, 360 "testUint16": 3x455, 361 "testUint32": 343443, 362 "testUint64": 545665757 363 }`, 364 expectedResult: testObject{}, 365 err: true, 366 }, 367 { 368 name: "basic-err-uint32", 369 json: `{ 370 "testStr": "hello world!", 371 "testInt": 4535, 372 "testBool": true, 373 "testFloat32": 2.345, 374 "testFloat64": 123.677, 375 "testInt8": 23, 376 "testInt16": 1245, 377 "testInt32": 456778, 378 "testInt64": 1446685358, 379 "testUint8": 255, 380 "testUint16": 3455, 381 "testUint32": 3x43443, 382 "testUint64": 545665757 383 }`, 384 expectedResult: testObject{}, 385 err: true, 386 }, 387 { 388 name: "basic-err-uint64", 389 json: `{ 390 "testStr": "hello world!", 391 "testInt": 4535, 392 "testBool": true, 393 "testFloat32": 2.345, 394 "testFloat64": 123.677, 395 "testInt8": 23, 396 "testInt16": 1245, 397 "testInt32": 456778, 398 "testInt64": 1446685358, 399 "testUint8": 255, 400 "testUint16": 3455, 401 "testUint32": 343443, 402 "testUint64": 5456x65757 403 }`, 404 expectedResult: testObject{}, 405 err: true, 406 }, 407 { 408 name: "basic-skip-data", 409 json: `{ 410 "testStr": "hello world!", 411 "testInt": 4535, 412 "testBool": true, 413 "testFloat32": 2.345, 414 "testFloat64": 123.677, 415 "testInt8": 23, 416 "skipObject": { 417 "escapedString": "string with escaped \\n new line" 418 }, 419 "testInt16": 1245, 420 "testInt32": 456778, 421 "testInt64": 1446685358, 422 "testUint8": 255, 423 "skipArray": [[],[],{}], 424 "testUint16": 3455, 425 "skipBool": true, 426 "skipNull": null, 427 "testUint32": 343443, 428 "testUint64": 545665757, 429 "skipString": "skipping string with escaped \\n new line", 430 "skipInt": 3, 431 }`, 432 expectedResult: testObject{ 433 testStr: "hello world!", 434 testInt: 4535, 435 testBool: true, 436 testFloat32: 2.345, 437 testFloat64: 123.677, 438 testInt8: 23, 439 testInt16: 1245, 440 testInt32: 456778, 441 testInt64: 1446685358, 442 testUint8: 255, 443 testUint16: 3455, 444 testUint32: 343443, 445 testUint64: 545665757, 446 }, 447 err: false, 448 }, 449 { 450 name: "basic-skip-data-error-uint8-negative", 451 json: `{ 452 "testStr": "hello world!", 453 "testInt": 4535, 454 "testBool": true, 455 "testFloat32": 2.345, 456 "testFloat64": 123.677, 457 "testInt8": 23, 458 "skipObject": { 459 "escapedString": "string with escaped \\n new line" 460 }, 461 "testInt16": 1245, 462 "testInt32": 456778, 463 "testInt64": 1446685358, 464 "testUint8": -255, 465 "skipArray": [[],[],{}], 466 "testUint16": 3455, 467 "skipBool": true, 468 "skipNull": null, 469 "testUint32": 343443, 470 "testUint64": 545665757, 471 "skipString": "skipping string with escaped \\n new line", 472 "skipInt": 3 473 }`, 474 expectedResult: testObject{ 475 testStr: "hello world!", 476 testInt: 4535, 477 testBool: true, 478 testFloat32: 2.345, 479 testFloat64: 123.677, 480 testInt8: 23, 481 testInt16: 1245, 482 testInt32: 456778, 483 testInt64: 1446685358, 484 testUint8: 0, 485 testUint16: 3455, 486 testUint32: 343443, 487 testUint64: 545665757, 488 }, 489 err: true, 490 }, 491 { 492 name: "skip-data-with-unicode", 493 json: `{ 494 "skipString": "hello\u1234\u2123", 495 "testStr": "hello world!", 496 "testInt": 4535, 497 "testBool": true, 498 "testFloat32": 2.345, 499 "testFloat64": 123.677, 500 "testInt8": 23, 501 "skipObject": { 502 "escapedString": "string with unicode \u1234\u1234\u1234" 503 }, 504 "testInt16": 1245, 505 "testInt32": 456778, 506 "testInt64": 1446685358, 507 "testUint8": 255, 508 "skipArray": [[],[],{}], 509 "testUint16": 3455, 510 "skipBool": true, 511 "skipNull": null, 512 "testUint32": 343443, 513 "testUint64": 545665757, 514 "skipInt": 3 515 }`, 516 expectedResult: testObject{ 517 testStr: "hello world!", 518 testInt: 4535, 519 testBool: true, 520 testFloat32: 2.345, 521 testFloat64: 123.677, 522 testInt8: 23, 523 testInt16: 1245, 524 testInt32: 456778, 525 testInt64: 1446685358, 526 testUint8: 255, 527 testUint16: 3455, 528 testUint32: 343443, 529 testUint64: 545665757, 530 }, 531 err: false, 532 }, 533 } 534 535 for _, testCase := range testCases { 536 t.Run(testCase.name, func(t *testing.T) { 537 s := testObject{} 538 dec := BorrowDecoder(strings.NewReader(testCase.json)) 539 defer dec.Release() 540 err := dec.Decode(&s) 541 if testCase.err { 542 t.Log(err) 543 assert.NotNil(t, err, "err should not be nil") 544 if testCase.errType != nil { 545 assert.IsType(t, testCase.errType, err, "err should be of the given type") 546 } 547 return 548 } 549 assert.Nil(t, err, "err should be nil") 550 if !testCase.skipCheckResult { 551 assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results") 552 } 553 }) 554 } 555 } 556 557 func TestDecodeObjectBasic0Keys(t *testing.T) { 558 testCases := []struct { 559 name string 560 json string 561 expectedResult testObject0Keys 562 err bool 563 errType interface{} 564 skipCheckResult bool 565 }{ 566 { 567 name: "basic", 568 json: `{ 569 "testStr": "hello world!", 570 "testInt": 4535, 571 "testBool": true, 572 "testFloat32": 2.345, 573 "testFloat64": 123.677, 574 "testInt8": 23, 575 "testInt16": 1245, 576 "testInt32": 456778, 577 "testInt64": 1446685358, 578 "testUint8": 255, 579 "testUint16": 3455, 580 "testUint32": 343443, 581 "testUint64": 545665757 582 }`, 583 expectedResult: testObject0Keys{ 584 testStr: "hello world!", 585 testInt: 4535, 586 testBool: true, 587 testFloat32: 2.345, 588 testFloat64: 123.677, 589 testInt8: 23, 590 testInt16: 1245, 591 testInt32: 456778, 592 testInt64: 1446685358, 593 testUint8: 255, 594 testUint16: 3455, 595 testUint32: 343443, 596 testUint64: 545665757, 597 }, 598 err: false, 599 }, 600 { 601 name: "basic-err-invalid-type", 602 json: `1`, 603 expectedResult: testObject0Keys{}, 604 err: true, 605 errType: InvalidUnmarshalError(""), 606 }, 607 { 608 name: "basic-err-invalid-json", 609 json: `hello`, 610 expectedResult: testObject0Keys{}, 611 err: true, 612 errType: InvalidJSONError(""), 613 }, 614 { 615 name: "basic-err-invalid-json", 616 json: `nall`, 617 expectedResult: testObject0Keys{}, 618 err: true, 619 errType: InvalidJSONError(""), 620 }, 621 { 622 name: "basic-err-invalid-type", 623 json: ``, 624 expectedResult: testObject0Keys{}, 625 err: true, 626 errType: InvalidJSONError(""), 627 }, 628 { 629 name: "basic-err", 630 json: `{ 631 "testStr": "hello world!", 632 "testInt": 453q5, 633 "testBool": trae, 634 "testFloat32": 2q.345, 635 "testFloat64": 12x3.677, 636 "testInt8": 2s3, 637 "testInt16": 1245, 638 "testInt32": 4567q78, 639 "testInt64": 14466e85358, 640 "testUint8": 2s55, 641 "testUint16": 345i5, 642 "testUint32": 343q443, 643 "testUint64": 5456657z57 644 }`, 645 expectedResult: testObject0Keys{}, 646 err: true, 647 }, 648 { 649 name: "basic-err2", 650 json: `{ 651 "testStr": "hello world!", 652 "testInt": 4535, 653 "testBool": true, 654 "testFloat32": 2.345, 655 "testFloat64": 123.677, 656 "testInt8": 23, 657 "testInt16": 1245, 658 "testInt32": 4567x78, 659 "testInt64": 1446685358, 660 "testUint8": 255, 661 "testUint16": 3455, 662 "testUint32": 343443, 663 "testUint64": 545665757 664 }`, 665 expectedResult: testObject0Keys{}, 666 err: true, 667 }, 668 { 669 name: "basic-err-float32", 670 json: `{ 671 "testStr": "hello world!", 672 "testInt": 4535, 673 "testBool": true, 674 "testFloat32": 2q.345, 675 "testFloat64": 123.677, 676 "testInt8": 23, 677 "testInt16": 1245, 678 "testInt32": 456778, 679 "testInt64": 1446685358, 680 "testUint8": 255, 681 "testUint16": 3455, 682 "testUint32": 343443, 683 "testUint64": 545665757 684 }`, 685 expectedResult: testObject0Keys{}, 686 err: true, 687 }, 688 { 689 name: "basic-err-float64", 690 json: `{ 691 "testStr": "hello world!", 692 "testInt": 4535, 693 "testBool": true, 694 "testFloat32": 2.345, 695 "testFloat64": 1x23.677, 696 "testInt8": 23, 697 "testInt16": 1245, 698 "testInt32": 456778, 699 "testInt64": 1446685358, 700 "testUint8": 255, 701 "testUint16": 3455, 702 "testUint32": 343443, 703 "testUint64": 545665757 704 }`, 705 expectedResult: testObject0Keys{}, 706 err: true, 707 }, 708 { 709 name: "basic-err3", 710 json: `{ 711 "testStr": "hello world!", 712 "testInt": 4535, 713 "testBool": true, 714 "testFloat32": 2.345, 715 "testFloat64": 123.677, 716 "testInt8": 2q3, 717 "testInt16": 1245, 718 "testInt32": 456778, 719 "testInt64": 1446685358, 720 "testUint8": 255, 721 "testUint16": 3455, 722 "testUint32": 343443, 723 "testUint64": 545665757 724 }`, 725 expectedResult: testObject0Keys{}, 726 err: true, 727 }, 728 { 729 name: "basic-err-int16", 730 json: `{ 731 "testStr": "hello world!", 732 "testInt": 4535, 733 "testBool": true, 734 "testFloat32": 2.345, 735 "testFloat64": 123.677, 736 "testInt8": 23, 737 "testInt16": 1x245, 738 "testInt32": 456778, 739 "testInt64": 1446685358, 740 "testUint8": 255, 741 "testUint16": 3455, 742 "testUint32": 343443, 743 "testUint64": 545665757 744 }`, 745 expectedResult: testObject0Keys{}, 746 err: true, 747 }, 748 { 749 name: "basic-err-int64", 750 json: `{ 751 "testStr": "hello world!", 752 "testInt": 4535, 753 "testBool": true, 754 "testFloat32": 2.345, 755 "testFloat64": 123.677, 756 "testInt8": 23, 757 "testInt16": 1245, 758 "testInt32": 456778, 759 "testInt64": 1446q685358, 760 "testUint8": 255, 761 "testUint16": 3455, 762 "testUint32": 343443, 763 "testUint64": 545665757 764 }`, 765 expectedResult: testObject0Keys{}, 766 err: true, 767 }, 768 { 769 name: "basic-err-uint8", 770 json: `{ 771 "testStr": "hello world!", 772 "testInt": 4535, 773 "testBool": true, 774 "testFloat32": 2.345, 775 "testFloat64": 123.677, 776 "testInt8": 23, 777 "testInt16": 1245, 778 "testInt32": 456778, 779 "testInt64": 1446685358, 780 "testUint8": 2x55, 781 "testUint16": 3455, 782 "testUint32": 343443, 783 "testUint64": 545665757 784 }`, 785 expectedResult: testObject0Keys{}, 786 err: true, 787 }, 788 { 789 name: "basic-err-uint16", 790 json: `{ 791 "testStr": "hello world!", 792 "testInt": 4535, 793 "testBool": true, 794 "testFloat32": 2.345, 795 "testFloat64": 123.677, 796 "testInt8": 23, 797 "testInt16": 1245, 798 "testInt32": 456778, 799 "testInt64": 1446685358, 800 "testUint8": 255, 801 "testUint16": 3x455, 802 "testUint32": 343443, 803 "testUint64": 545665757 804 }`, 805 expectedResult: testObject0Keys{}, 806 err: true, 807 }, 808 { 809 name: "basic-err-uint32", 810 json: `{ 811 "testStr": "hello world!", 812 "testInt": 4535, 813 "testBool": true, 814 "testFloat32": 2.345, 815 "testFloat64": 123.677, 816 "testInt8": 23, 817 "testInt16": 1245, 818 "testInt32": 456778, 819 "testInt64": 1446685358, 820 "testUint8": 255, 821 "testUint16": 3455, 822 "testUint32": 3x43443, 823 "testUint64": 545665757 824 }`, 825 expectedResult: testObject0Keys{}, 826 err: true, 827 }, 828 { 829 name: "basic-err-uint64", 830 json: `{ 831 "testStr": "hello world!", 832 "testInt": 4535, 833 "testBool": true, 834 "testFloat32": 2.345, 835 "testFloat64": 123.677, 836 "testInt8": 23, 837 "testInt16": 1245, 838 "testInt32": 456778, 839 "testInt64": 1446685358, 840 "testUint8": 255, 841 "testUint16": 3455, 842 "testUint32": 343443, 843 "testUint64": 5456x65757 844 }`, 845 expectedResult: testObject0Keys{}, 846 err: true, 847 }, 848 { 849 name: "basic-skip-data", 850 json: `{ 851 "testStr": "hello world!", 852 "testInt": 4535, 853 "testBool": true, 854 "testFloat32": 2.345, 855 "testFloat64": 123.677, 856 "testInt8": 23, 857 "skipObject": { 858 "escapedString": "string with escaped \\n new line" 859 }, 860 "testInt16": 1245, 861 "testInt32": 456778, 862 "testInt64": 1446685358, 863 "testUint8": 255, 864 "skipArray": [[],[],{}], 865 "testUint16": 3455, 866 "skipBool": true, 867 "skipNull": null, 868 "testUint32": 343443, 869 "testUint64": 545665757, 870 "skipString": "skipping string with escaped \\n new line", 871 "skipInt": 3, 872 }`, 873 expectedResult: testObject0Keys{ 874 testStr: "hello world!", 875 testInt: 4535, 876 testBool: true, 877 testFloat32: 2.345, 878 testFloat64: 123.677, 879 testInt8: 23, 880 testInt16: 1245, 881 testInt32: 456778, 882 testInt64: 1446685358, 883 testUint8: 255, 884 testUint16: 3455, 885 testUint32: 343443, 886 testUint64: 545665757, 887 }, 888 err: false, 889 }, 890 } 891 892 for _, testCase := range testCases { 893 t.Run(testCase.name, func(t *testing.T) { 894 s := testObject0Keys{} 895 dec := BorrowDecoder(strings.NewReader(testCase.json)) 896 defer dec.Release() 897 err := dec.Decode(&s) 898 if testCase.err { 899 t.Log(err) 900 assert.NotNil(t, err, "err should not be nil") 901 if testCase.errType != nil { 902 assert.IsType(t, testCase.errType, err, "err should be of the given type") 903 } 904 return 905 } 906 assert.Nil(t, err, "err should be nil") 907 if !testCase.skipCheckResult { 908 assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results") 909 } 910 }) 911 } 912 for _, testCase := range testCases { 913 t.Run(testCase.name, func(t *testing.T) { 914 s := testObject0Keys{} 915 err := UnmarshalJSONObject([]byte(testCase.json), &s) 916 if testCase.err { 917 t.Log(err) 918 assert.NotNil(t, err, "err should not be nil") 919 if testCase.errType != nil { 920 assert.IsType(t, testCase.errType, err, "err should be of the given type") 921 } 922 return 923 } 924 assert.Nil(t, err, "err should be nil") 925 if !testCase.skipCheckResult { 926 assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results") 927 } 928 }) 929 } 930 } 931 932 type ObjectNull struct { 933 SubObject *ObjectNull 934 SubArray *testSliceBools 935 } 936 937 func (o *ObjectNull) UnmarshalJSONObject(dec *Decoder, k string) error { 938 switch k { 939 case "subobject": 940 return dec.ObjectNull(&o.SubObject) 941 case "subarray": 942 return dec.AddArrayNull(&o.SubArray) 943 } 944 return nil 945 } 946 947 func (o *ObjectNull) NKeys() int { 948 return 2 949 } 950 951 type ObjectNullZeroNKeys struct { 952 SubObject *ObjectNullZeroNKeys 953 SubArray *testSliceBools 954 } 955 956 func (o *ObjectNullZeroNKeys) UnmarshalJSONObject(dec *Decoder, k string) error { 957 switch k { 958 case "subobject": 959 return dec.AddObjectNull(&o.SubObject) 960 case "subarray": 961 return dec.AddArrayNull(&o.SubArray) 962 } 963 return nil 964 } 965 966 func (o *ObjectNullZeroNKeys) NKeys() int { 967 return 0 968 } 969 970 func TestDecodeObjectNull(t *testing.T) { 971 t.Run("sub obj should not be nil", func(t *testing.T) { 972 var o = &ObjectNull{} 973 var err = UnmarshalJSONObject([]byte(`{"subobject": {},"subarray":[true]}`), o) 974 assert.Nil(t, err) 975 assert.NotNil(t, o.SubObject) 976 assert.NotNil(t, o.SubArray) 977 }) 978 t.Run("sub obj and sub array should be nil", func(t *testing.T) { 979 var o = &ObjectNull{} 980 var err = UnmarshalJSONObject([]byte(`{"subobject": null,"subarray": null}`), o) 981 assert.Nil(t, err) 982 assert.Nil(t, o.SubObject) 983 assert.Nil(t, o.SubArray) 984 }) 985 t.Run( 986 "sub obj should not be be nil", 987 func(t *testing.T) { 988 var o = &ObjectNull{} 989 var err = UnmarshalJSONObject([]byte(`{"subobject":{"subobject":{}}}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 990 return dec.ObjectNull(&o.SubObject) 991 })) 992 assert.Nil(t, err) 993 assert.NotNil(t, o.SubObject) 994 }, 995 ) 996 t.Run( 997 "sub obj should be nil", 998 func(t *testing.T) { 999 var o = &ObjectNull{} 1000 var err = UnmarshalJSONObject([]byte(`{"subobject":null}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1001 return dec.ObjectNull(&o.SubObject) 1002 })) 1003 assert.Nil(t, err) 1004 assert.Nil(t, o.SubObject) 1005 }, 1006 ) 1007 t.Run( 1008 "skip data", 1009 func(t *testing.T) { 1010 var o = &ObjectNull{} 1011 var err = UnmarshalJSONObject([]byte(`{ 1012 "subobject": { 1013 "subobject": {}, 1014 "subarray": [], 1015 "subarray": [], 1016 "skipped": "" 1017 } 1018 }`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1019 return dec.ObjectNull(&o.SubObject) 1020 })) 1021 assert.Nil(t, err) 1022 assert.NotNil(t, o.SubObject) 1023 assert.Nil(t, o.SubArray) 1024 }, 1025 ) 1026 t.Run( 1027 "skip data not child", 1028 func(t *testing.T) { 1029 var o = &ObjectNull{} 1030 var dec = NewDecoder(strings.NewReader(`{ 1031 "subobject": {}, 1032 "subarray": [], 1033 "subarray": [], 1034 "skipped": "" 1035 }`)) 1036 var _, err = dec.decodeObjectNull(&o) 1037 assert.Nil(t, err) 1038 assert.NotNil(t, o.SubObject) 1039 }, 1040 ) 1041 t.Run( 1042 "err empty json", 1043 func(t *testing.T) { 1044 var o = &ObjectNull{} 1045 var dec = NewDecoder(strings.NewReader(``)) 1046 var _, err = dec.decodeObjectNull(&o) 1047 assert.NotNil(t, err) 1048 }, 1049 ) 1050 t.Run( 1051 "should return an error as type is not ptr", 1052 func(t *testing.T) { 1053 var err = UnmarshalJSONObject([]byte(`{"key":{}}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1054 return dec.ObjectNull("") 1055 })) 1056 assert.NotNil(t, err) 1057 assert.Equal(t, ErrUnmarshalPtrExpected, err) 1058 }, 1059 ) 1060 t.Run( 1061 "should return an error as type is not ptr", 1062 func(t *testing.T) { 1063 var err = UnmarshalJSONObject([]byte(`{"key":[]}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1064 return dec.ArrayNull("") 1065 })) 1066 assert.NotNil(t, err) 1067 assert.Equal(t, ErrUnmarshalPtrExpected, err) 1068 }, 1069 ) 1070 t.Run( 1071 "should return an error as type is not ptr to UnmarshalerJSONObject", 1072 func(t *testing.T) { 1073 var err = UnmarshalJSONObject([]byte(`{"key":{}}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1074 var strPtr = new(string) 1075 return dec.ObjectNull(&strPtr) 1076 })) 1077 assert.NotNil(t, err) 1078 assert.IsType(t, InvalidUnmarshalError(""), err) 1079 }, 1080 ) 1081 t.Run( 1082 "should return an error as type is not ptr to UnmarshalerJSONObject", 1083 func(t *testing.T) { 1084 var err = UnmarshalJSONObject([]byte(`{"key":[]}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1085 var strPtr = new(string) 1086 return dec.ArrayNull(&strPtr) 1087 })) 1088 assert.NotNil(t, err) 1089 assert.IsType(t, InvalidUnmarshalError(""), err) 1090 }, 1091 ) 1092 t.Run( 1093 "should return an error as type is not ptr to UnmarshalerJSONObject", 1094 func(t *testing.T) { 1095 var err = UnmarshalJSONObject([]byte(`{"key":{}}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1096 var strPtr = new(string) 1097 return dec.ArrayNull(&strPtr) 1098 })) 1099 assert.NotNil(t, err) 1100 assert.IsType(t, InvalidUnmarshalError(""), err) 1101 }, 1102 ) 1103 t.Run( 1104 "should return an error as type is not ptr to UnmarshalerJSONObject", 1105 func(t *testing.T) { 1106 var err = UnmarshalJSONObject([]byte(`{"key":"`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1107 var strPtr = new(string) 1108 return dec.ArrayNull(&strPtr) 1109 })) 1110 assert.NotNil(t, err) 1111 assert.IsType(t, InvalidJSONError(""), err) 1112 }, 1113 ) 1114 t.Run( 1115 "skip data", 1116 func(t *testing.T) { 1117 var err = UnmarshalJSONObject([]byte(`{"key": ""}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1118 var strPtr = new(string) 1119 return dec.ObjectNull(&strPtr) 1120 })) 1121 assert.NotNil(t, err) 1122 assert.IsType(t, InvalidUnmarshalError(""), err) 1123 }, 1124 ) 1125 t.Run( 1126 "invalid JSON for object", 1127 func(t *testing.T) { 1128 var o = &ObjectNull{} 1129 var err = UnmarshalJSONObject([]byte(`{"subobject":{"subobject":{"a":a}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1130 return dec.ObjectNull(&o.SubObject) 1131 })) 1132 assert.NotNil(t, err) 1133 assert.IsType(t, InvalidJSONError(""), err) 1134 }, 1135 ) 1136 t.Run( 1137 "invalid JSON for object", 1138 func(t *testing.T) { 1139 var o = &ObjectNull{} 1140 var err = UnmarshalJSONObject([]byte(`{"subobject":{"subobject":a}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1141 return dec.ObjectNull(&o.SubObject) 1142 })) 1143 assert.NotNil(t, err) 1144 assert.IsType(t, InvalidJSONError(""), err) 1145 }, 1146 ) 1147 t.Run( 1148 "invalid JSON for object", 1149 func(t *testing.T) { 1150 var o = &ObjectNull{} 1151 var err = UnmarshalJSONObject([]byte(`{"subobject":{"subobject":{"sub}}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1152 return dec.ObjectNull(&o.SubObject) 1153 })) 1154 assert.NotNil(t, err) 1155 assert.IsType(t, InvalidJSONError(""), err) 1156 }, 1157 ) 1158 t.Run( 1159 "invalid JSON for object", 1160 func(t *testing.T) { 1161 var o = &testSliceBools{} 1162 var err = UnmarshalJSONObject([]byte(`{"subobject":a`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1163 return dec.ArrayNull(&o) 1164 })) 1165 assert.NotNil(t, err) 1166 assert.IsType(t, InvalidJSONError(""), err) 1167 }, 1168 ) 1169 t.Run( 1170 "invalid JSON for object", 1171 func(t *testing.T) { 1172 var err = UnmarshalJSONObject([]byte(`{"key":a`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1173 var strPtr = new(string) 1174 return dec.ObjectNull(&strPtr) 1175 })) 1176 assert.NotNil(t, err) 1177 assert.IsType(t, InvalidJSONError(""), err) 1178 }, 1179 ) 1180 t.Run( 1181 "invalid JSON for object", 1182 func(t *testing.T) { 1183 var err = UnmarshalJSONObject([]byte(`{"subobject": {},"}`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1184 var o = &ObjectNull{} 1185 return dec.ObjectNull(&o) 1186 })) 1187 assert.NotNil(t, err) 1188 assert.IsType(t, InvalidJSONError(""), err) 1189 }, 1190 ) 1191 t.Run( 1192 "invalid JSON for object", 1193 func(t *testing.T) { 1194 var o = &ObjectNull{} 1195 var err = UnmarshalJSONObject([]byte(`{"subobject": a`), o) 1196 assert.NotNil(t, err) 1197 assert.IsType(t, InvalidJSONError(""), err) 1198 }, 1199 ) 1200 t.Run( 1201 "invalid JSON for object", 1202 func(t *testing.T) { 1203 var o = &ObjectNull{} 1204 var err = UnmarshalJSONObject([]byte(`{"subobject": na`), o) 1205 assert.NotNil(t, err) 1206 assert.IsType(t, InvalidJSONError(""), err) 1207 }, 1208 ) 1209 t.Run( 1210 "zero nkeys, no error, two keys", 1211 func(t *testing.T) { 1212 var o = &ObjectNullZeroNKeys{} 1213 var err = UnmarshalJSONObject([]byte(`{ 1214 "subobject": { 1215 "subobject": { 1216 "subobject":{} 1217 }, 1218 "subarray": [] 1219 } 1220 }`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1221 return dec.ObjectNull(&o.SubObject) 1222 })) 1223 assert.Nil(t, err) 1224 }, 1225 ) 1226 t.Run( 1227 "zero nkeys, no error, two keys, skip data", 1228 func(t *testing.T) { 1229 var o = &ObjectNullZeroNKeys{} 1230 var err = UnmarshalJSONObject([]byte(`{ 1231 "subobject": { 1232 "subobject": { 1233 "subobject":{} 1234 }, 1235 "subarray": [], 1236 "skipped": 1 1237 } 1238 }`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1239 return dec.ObjectNull(&o.SubObject) 1240 })) 1241 assert.Nil(t, err) 1242 }, 1243 ) 1244 t.Run( 1245 "zero nkeys, error skip data", 1246 func(t *testing.T) { 1247 var o = &ObjectNullZeroNKeys{} 1248 var err = UnmarshalJSONObject([]byte(`{ 1249 "subobject": { 1250 "subobject": { 1251 "subobject":{} 1252 }, 1253 "subarray": [], 1254 "skippedInvalid": "q 1255 } 1256 }`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1257 return dec.ObjectNull(&o.SubObject) 1258 })) 1259 assert.NotNil(t, err) 1260 assert.IsType(t, InvalidJSONError(""), err) 1261 }, 1262 ) 1263 t.Run( 1264 "zero nkeys, error invalid json in keys", 1265 func(t *testing.T) { 1266 var o = &ObjectNullZeroNKeys{} 1267 var err = UnmarshalJSONObject([]byte(`{ 1268 "subobject": { 1269 "subobj 1270 } 1271 }`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1272 return dec.ObjectNull(&o.SubObject) 1273 })) 1274 assert.NotNil(t, err) 1275 assert.IsType(t, InvalidJSONError(""), err) 1276 }, 1277 ) 1278 t.Run( 1279 "zero nkeys, error invalid json, sub object", 1280 func(t *testing.T) { 1281 var o = &ObjectNullZeroNKeys{} 1282 var err = UnmarshalJSONObject([]byte(`{ 1283 "subobject": { 1284 "subobject": { 1285 "subobj 1286 } 1287 } 1288 }`), DecodeObjectFunc(func(dec *Decoder, k string) error { 1289 return dec.ObjectNull(&o.SubObject) 1290 })) 1291 assert.NotNil(t, err) 1292 assert.IsType(t, InvalidJSONError(""), err) 1293 }, 1294 ) 1295 } 1296 1297 func TestDecodeObjectComplex(t *testing.T) { 1298 testCases := []struct { 1299 name string 1300 json string 1301 expectedResult testObjectComplex 1302 err bool 1303 errType interface{} 1304 skipCheckResult bool 1305 }{ 1306 { 1307 name: "basic", 1308 json: `{ 1309 "testSubObject": {}, 1310 "testSubSliceInts": [1,2] 1311 }`, 1312 expectedResult: testObjectComplex{ 1313 testSubObject: &testObject{}, 1314 testSubSliceInts: &testSliceInts{1, 2}, 1315 }, 1316 err: false, 1317 }, 1318 { 1319 name: "complex", 1320 json: `{ 1321 "testSubObject": { 1322 "testStr": "some string", 1323 "testInt":124465, 1324 "testUint16":120, 1325 "testUint8":15, 1326 "testInt16":-135, 1327 "testInt8":-23 1328 }, 1329 "testSubSliceInts": [1,2,3,4,5], 1330 "testStr": "some \n string" 1331 }`, 1332 expectedResult: testObjectComplex{ 1333 testSubObject: &testObject{ 1334 testStr: "some string", 1335 testInt: 124465, 1336 testUint16: 120, 1337 testUint8: 15, 1338 testInt16: -135, 1339 testInt8: -23, 1340 }, 1341 testSubSliceInts: &testSliceInts{1, 2, 3, 4, 5}, 1342 testStr: "some \n string", 1343 }, 1344 err: false, 1345 }, 1346 { 1347 name: "complex-json-err", 1348 json: `{"testSubObject":{"testStr":"some string,"testInt":124465,"testUint16":120, "testUint8":15,"testInt16":-135,"testInt8":-23},"testSubSliceInts":[1,2],"testStr":"some \n string"}`, 1349 expectedResult: testObjectComplex{ 1350 testSubObject: &testObject{}, 1351 }, 1352 err: true, 1353 }, 1354 } 1355 1356 for _, testCase := range testCases { 1357 t.Run(testCase.name, func(t *testing.T) { 1358 s := testObjectComplex{ 1359 testSubObject: &testObject{}, 1360 testSubSliceInts: &testSliceInts{}, 1361 } 1362 dec := BorrowDecoder(strings.NewReader(testCase.json)) 1363 defer dec.Release() 1364 err := dec.Decode(&s) 1365 if testCase.err { 1366 t.Log(err) 1367 assert.NotNil(t, err, "err should not be nil") 1368 if testCase.errType != nil { 1369 assert.IsType(t, testCase.errType, err, "err should be of the given type") 1370 } 1371 return 1372 } 1373 assert.Nil(t, err, "err should be nil") 1374 if !testCase.skipCheckResult { 1375 assert.Equal(t, testCase.expectedResult, s, "value at given index should be the same as expected results") 1376 } 1377 }) 1378 } 1379 } 1380 1381 func assertResult(t *testing.T, v *TestObj, err error) { 1382 assert.Nil(t, err, "Err must be nil") 1383 assert.Equal(t, 245, v.test, "v.test must be equal to 245") 1384 assert.Equal(t, 246, v.test2, "v.test2 must be equal to 246") 1385 assert.Equal(t, "string", v.test3, "v.test3 must be equal to 'string'") 1386 assert.Equal(t, "complex string with spaces and some slashes\"", v.test4, "v.test4 must be equal to 'string'") 1387 assert.Equal(t, -1.15657654376543, v.test5, "v.test5 must be equal to 1.15") 1388 assert.Len(t, v.testArr, 2, "v.testArr must be of len 2") 1389 1390 assert.Equal(t, 121, v.testSubObj.test3, "v.testSubObj.test3 must be equal to 121") 1391 assert.Equal(t, 122, v.testSubObj.test4, "v.testSubObj.test4 must be equal to 122") 1392 assert.Equal(t, "string", v.testSubObj.test5, "v.testSubObj.test5 must be equal to 'string'") 1393 assert.Equal(t, 150, v.testSubObj.testSubSubObj.test3, "v.testSubObj.testSubSubObj.test3 must be equal to 150") 1394 assert.Equal(t, 150, v.testSubObj.testSubSubObj2.test3, "v.testSubObj.testSubSubObj2.test3 must be equal to 150") 1395 1396 assert.Equal(t, 122, v.testSubObj2.test3, "v.testSubObj2.test3 must be equal to 121") 1397 assert.Equal(t, 123, v.testSubObj2.test4, "v.testSubObj2.test4 must be equal to 122") 1398 assert.Equal(t, "string", v.testSubObj2.test5, "v.testSubObj2.test5 must be equal to 'string'") 1399 assert.Equal(t, 151, v.testSubObj2.testSubSubObj.test3, "v.testSubObj2.testSubSubObj.test must be equal to 150") 1400 } 1401 1402 func TestDecoderObject(t *testing.T) { 1403 json := []byte(`{ 1404 "test": 245, 1405 "test2": 246, 1406 "test3": "string", 1407 "test4": "complex string with spaces and some slashes\"", 1408 "test5": -1.15657654376543, 1409 "testNull": null, 1410 "testArr": [ 1411 { 1412 "test": 245, 1413 "test2": 246 1414 }, 1415 { 1416 "test": 245, 1417 "test2": 246 1418 } 1419 ], 1420 "testSubObj": { 1421 "test": 121, 1422 "test2": 122, 1423 "testNull": null, 1424 "testSubSubObj": { 1425 "test": 150, 1426 "testNull": null 1427 }, 1428 "testSubSubObj2": { 1429 "test": 150 1430 }, 1431 "test3": "string" 1432 "testNull": null, 1433 }, 1434 "testSubObj2": { 1435 "test": 122, 1436 "test3": "string" 1437 "testSubSubObj": { 1438 "test": 151 1439 }, 1440 "test2": 123 1441 } 1442 }`) 1443 v := &TestObj{} 1444 err := Unmarshal(json, v) 1445 assertResult(t, v, err) 1446 } 1447 1448 func TestDecodeObjectJSONNull(t *testing.T) { 1449 json := []byte(`null`) 1450 v := &TestObj{} 1451 err := Unmarshal(json, v) 1452 assert.Nil(t, err, "Err must be nil") 1453 assert.Equal(t, v.test, 0, "v.test must be 0 val") 1454 } 1455 1456 var jsonComplex = []byte(`{ 1457 "test": "{\"test\":\"1\",\"test1\":2}", 1458 "test2\n": "\\\\\\\\\n", 1459 "testArrSkip": ["testString with escaped \\\" quotes"], 1460 "testSkipString": "skip \\ string with \n escaped char \" ", 1461 "testSkipObject": { 1462 "testSkipSubObj": { 1463 "test": "test" 1464 } 1465 }, 1466 "testSkipNumber": 123.23, 1467 "testSkipNumber2": 123.23 , 1468 "testBool": true, 1469 "testSkipBoolTrue": true, 1470 "testSkipBoolFalse": false, 1471 "testSkipBoolNull": null, 1472 "testSub": { 1473 "test": "{\"test\":\"1\",\"test1\":2}", 1474 "test2\n": "[1,2,3]", 1475 "test3": 1, 1476 "testObjSkip": { 1477 "test": "test string with escaped \" quotes" 1478 }, 1479 "testStrSkip" : "test" 1480 }, 1481 "testBoolSkip": false, 1482 "testObjInvalidType": "somestring", 1483 "testArrSkip2": [[],["someString"]], 1484 "test3": 1 1485 }`) 1486 1487 type jsonObjectComplex struct { 1488 Test string 1489 Test2 string 1490 Test3 int 1491 Test4 bool 1492 testSub *jsonObjectComplex 1493 testObjInvalidType *jsonObjectComplex 1494 } 1495 1496 func (j *jsonObjectComplex) UnmarshalJSONObject(dec *Decoder, key string) error { 1497 switch key { 1498 case "test": 1499 return dec.AddString(&j.Test) 1500 case "test2\n": 1501 return dec.AddString(&j.Test2) 1502 case "test3": 1503 return dec.AddInt(&j.Test3) 1504 case "testBool": 1505 return dec.AddBool(&j.Test4) 1506 case "testSub": 1507 j.testSub = &jsonObjectComplex{} 1508 return dec.AddObject(j.testSub) 1509 case "testObjInvalidType": 1510 j.testObjInvalidType = &jsonObjectComplex{} 1511 return dec.AddObject(j.testObjInvalidType) 1512 } 1513 return nil 1514 } 1515 1516 func (j *jsonObjectComplex) NKeys() int { 1517 return 6 1518 } 1519 1520 func TestDecodeObjComplex(t *testing.T) { 1521 result := jsonObjectComplex{} 1522 err := UnmarshalJSONObject(jsonComplex, &result) 1523 assert.NotNil(t, err, "err should not be as invalid type as been encountered nil") 1524 assert.Equal(t, `Cannot unmarshal JSON to type '*gojay.jsonObjectComplex'`, err.Error(), "err should not be as invalid type as been encountered nil") 1525 assert.Equal(t, `{"test":"1","test1":2}`, result.Test, "result.Test is not expected value") 1526 assert.Equal(t, "\\\\\\\\\n", result.Test2, "result.Test2 is not expected value") 1527 assert.Equal(t, 1, result.Test3, "result.test3 is not expected value") 1528 assert.Equal(t, `{"test":"1","test1":2}`, result.testSub.Test, "result.testSub.test is not expected value") 1529 assert.Equal(t, `[1,2,3]`, result.testSub.Test2, "result.testSub.test2 is not expected value") 1530 assert.Equal(t, 1, result.testSub.Test3, "result.testSub.test3 is not expected value") 1531 assert.Equal(t, true, result.Test4, "result.Test4 is not expected value, should be true") 1532 } 1533 1534 type jsonDecodePartial struct { 1535 Test string 1536 Test2 string 1537 } 1538 1539 func (j *jsonDecodePartial) UnmarshalJSONObject(dec *Decoder, key string) error { 1540 switch key { 1541 case "test": 1542 return dec.AddString(&j.Test) 1543 case `test2`: 1544 return dec.AddString(&j.Test2) 1545 } 1546 return nil 1547 } 1548 1549 func (j *jsonDecodePartial) NKeys() int { 1550 return 2 1551 } 1552 1553 func TestDecodeObjectPartial(t *testing.T) { 1554 result := jsonDecodePartial{} 1555 dec := NewDecoder(nil) 1556 dec.data = []byte(`{ 1557 "test": "test", 1558 "test2": "test", 1559 "testArrSkip": ["test"], 1560 "testSkipString": "test", 1561 "testSkipNumber": 123.23 1562 }`) 1563 dec.length = len(dec.data) 1564 err := dec.DecodeObject(&result) 1565 assert.Nil(t, err, "err should be nil") 1566 assert.NotEqual(t, len(dec.data), dec.cursor) 1567 } 1568 1569 func TestDecoderObjectInvalidJSON(t *testing.T) { 1570 result := jsonDecodePartial{} 1571 dec := NewDecoder(nil) 1572 dec.data = []byte(`{ 1573 "test2": "test", 1574 "testArrSkip": ["test"], 1575 "testSkipString": "testInvalidJSON\\\\ 1576 }`) 1577 dec.length = len(dec.data) 1578 err := dec.DecodeObject(&result) 1579 assert.NotNil(t, err, "Err must not be nil as JSON is invalid") 1580 assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'") 1581 } 1582 1583 type myMap map[string]string 1584 1585 func (m myMap) UnmarshalJSONObject(dec *Decoder, k string) error { 1586 str := "" 1587 err := dec.AddString(&str) 1588 if err != nil { 1589 return err 1590 } 1591 m[k] = str 1592 return nil 1593 } 1594 1595 // return 0 to parse all keys 1596 func (m myMap) NKeys() int { 1597 return 0 1598 } 1599 1600 func TestDecoderObjectMap(t *testing.T) { 1601 json := `{ 1602 "test": "string", 1603 "test2": "string", 1604 "test3": "string", 1605 "test4": "string", 1606 "test5": "string", 1607 }` 1608 m := myMap(make(map[string]string)) 1609 dec := BorrowDecoder(strings.NewReader(json)) 1610 err := dec.Decode(m) 1611 1612 assert.Nil(t, err, "err should be nil") 1613 assert.Len(t, m, 5, "len of m should be 5") 1614 } 1615 1616 func TestDecoderObjectDecoderAPI(t *testing.T) { 1617 json := `{ 1618 "test": 245, 1619 "test2": 246, 1620 "test3": "string", 1621 "test4": "complex string with spaces and some slashes\"", 1622 "test5": -1.15657654376543, 1623 "testNull": null, 1624 "testArr": [ 1625 { 1626 "test": 245, 1627 "test2": 246 1628 }, 1629 { 1630 "test": 245, 1631 "test2": 246 1632 } 1633 ], 1634 "testSubObj": { 1635 "test": 121, 1636 "test2": 122, 1637 "testNull": null, 1638 "testSubSubObj": { 1639 "test": 150, 1640 "testNull": null 1641 }, 1642 "testSubSubObj2": { 1643 "test": 150 1644 }, 1645 "test3": "string" 1646 "testNull": null, 1647 }, 1648 "testSubObj2": { 1649 "test": 122, 1650 "test3": "string" 1651 "testSubSubObj": { 1652 "test": 151 1653 }, 1654 "test2": 123 1655 } 1656 }` 1657 v := &TestObj{} 1658 dec := NewDecoder(strings.NewReader(json)) 1659 err := dec.DecodeObject(v) 1660 assertResult(t, v, err) 1661 } 1662 1663 type ReadCloser struct { 1664 json []byte 1665 } 1666 1667 func (r *ReadCloser) Read(b []byte) (int, error) { 1668 copy(b, r.json) 1669 return len(r.json), io.EOF 1670 } 1671 1672 func TestDecoderObjectDecoderAPIReadCloser(t *testing.T) { 1673 readCloser := ReadCloser{ 1674 json: []byte(`{ 1675 "test": "string", 1676 "test2": "string", 1677 "test3": "string", 1678 "test4": "string", 1679 "test5": "string", 1680 }`), 1681 } 1682 m := myMap(make(map[string]string)) 1683 dec := NewDecoder(&readCloser) 1684 err := dec.DecodeObject(m) 1685 assert.Nil(t, err, "err should be nil") 1686 assert.Len(t, m, 5, "len of m should be 5") 1687 } 1688 1689 func TestDecoderObjectDecoderAPIFuncReadCloser(t *testing.T) { 1690 readCloser := ReadCloser{ 1691 json: []byte(`{ 1692 "test": "string", 1693 "test2": "string", 1694 "test3": "string", 1695 "test4": "string", 1696 "test5": "string", 1697 }`), 1698 } 1699 m := myMap(make(map[string]string)) 1700 dec := NewDecoder(&readCloser) 1701 err := dec.DecodeObject(DecodeObjectFunc(func(dec *Decoder, k string) error { 1702 str := "" 1703 err := dec.AddString(&str) 1704 if err != nil { 1705 return err 1706 } 1707 m[k] = str 1708 return nil 1709 })) 1710 assert.Nil(t, err, "err should be nil") 1711 assert.Len(t, m, 5, "len of m should be 5") 1712 } 1713 1714 func TestDecoderObjectDecoderInvalidJSONError(t *testing.T) { 1715 v := &TestObj{} 1716 dec := NewDecoder(strings.NewReader(`{"err:}`)) 1717 err := dec.DecodeObject(v) 1718 assert.NotNil(t, err, "Err must not be nil as JSON is invalid") 1719 assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'") 1720 } 1721 1722 func TestDecoderObjectDecoderInvalidJSONError2(t *testing.T) { 1723 v := &TestSubObj{} 1724 dec := NewDecoder(strings.NewReader(`{"err:}`)) 1725 err := dec.DecodeObject(v) 1726 assert.NotNil(t, err, "Err must not be nil as JSON is invalid") 1727 assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'") 1728 } 1729 1730 func TestDecoderObjectDecoderInvalidJSONError3(t *testing.T) { 1731 v := &TestSubObj{} 1732 dec := NewDecoder(strings.NewReader(`{"err":"test}`)) 1733 err := dec.DecodeObject(v) 1734 assert.NotNil(t, err, "Err must not be nil as JSON is invalid") 1735 assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'") 1736 } 1737 1738 func TestDecoderObjectDecoderInvalidJSONError4(t *testing.T) { 1739 testArr := testSliceInts{} 1740 dec := NewDecoder(strings.NewReader(`hello`)) 1741 err := dec.DecodeArray(&testArr) 1742 assert.NotNil(t, err, "Err must not be nil as JSON is invalid") 1743 assert.IsType(t, InvalidJSONError(""), err, "err message must be 'Invalid JSON'") 1744 } 1745 1746 func TestDecoderObjectPoolError(t *testing.T) { 1747 result := jsonDecodePartial{} 1748 dec := NewDecoder(nil) 1749 dec.Release() 1750 defer func() { 1751 err := recover() 1752 assert.NotNil(t, err, "err shouldnt be nil") 1753 assert.IsType(t, InvalidUsagePooledDecoderError(""), err, "err should be of type InvalidUsagePooledDecoderError") 1754 }() 1755 _ = dec.DecodeObject(&result) 1756 assert.True(t, false, "should not be called as decoder should have panicked") 1757 } 1758 1759 func TestNextKey(t *testing.T) { 1760 testCases := []struct { 1761 name string 1762 json string 1763 expectedValue string 1764 err bool 1765 }{ 1766 { 1767 name: "basic", 1768 json: `"key":"value"`, 1769 expectedValue: "key", 1770 }, 1771 { 1772 name: "basic-err", 1773 json: ``, 1774 expectedValue: "", 1775 err: true, 1776 }, 1777 { 1778 name: "basic-err2", 1779 json: `"key"`, 1780 expectedValue: "", 1781 err: true, 1782 }, 1783 { 1784 name: "basic-err3", 1785 json: `"key`, 1786 expectedValue: "", 1787 err: true, 1788 }, 1789 } 1790 for _, testCase := range testCases { 1791 t.Run(testCase.name, func(t *testing.T) { 1792 dec := BorrowDecoder(strings.NewReader(testCase.json)) 1793 s, _, err := dec.nextKey() 1794 if testCase.err { 1795 assert.NotNil(t, err, "err should not be nil") 1796 return 1797 } 1798 assert.Nil(t, err, "err should be nil") 1799 assert.Equal(t, testCase.expectedValue, s, fmt.Sprintf("s should be '%s'", testCase.expectedValue)) 1800 }) 1801 } 1802 } 1803 1804 func TestSkipObject(t *testing.T) { 1805 testCases := []struct { 1806 name string 1807 json string 1808 err bool 1809 }{ 1810 { 1811 name: "basic", 1812 json: `"key":"value"}`, 1813 }, 1814 { 1815 name: "basic-escape-solidus", 1816 json: `"key":"value\/solidus"}`, 1817 }, 1818 { 1819 name: "basic-escaped", 1820 json: `"key":"value\\\\\\\" hello"}`, 1821 }, 1822 { 1823 name: "basic-escaped", 1824 json: `"key":"value\\\\\\\\"}`, 1825 }, 1826 { 1827 name: "basic-err", 1828 json: ``, 1829 err: true, 1830 }, 1831 { 1832 name: "basic-err2", 1833 json: `{"key":"value"`, 1834 err: true, 1835 }, 1836 { 1837 name: "basic-err2", 1838 json: `"key":"value\n"}`, 1839 err: false, 1840 }, 1841 } 1842 for _, testCase := range testCases { 1843 t.Run(testCase.name, func(t *testing.T) { 1844 dec := BorrowDecoder(strings.NewReader(testCase.json)) 1845 defer dec.Release() 1846 _, err := dec.skipObject() 1847 if testCase.err { 1848 assert.NotNil(t, err, "err should not be nil") 1849 return 1850 } 1851 assert.Nil(t, err, "err should be nil") 1852 }) 1853 } 1854 } 1855 1856 func TestSkipData(t *testing.T) { 1857 testCases := []struct { 1858 name string 1859 err bool 1860 json string 1861 }{ 1862 { 1863 name: "skip-bool-false-err", 1864 json: `fulse`, 1865 err: true, 1866 }, 1867 { 1868 name: "skip-bool-true-err", 1869 json: `trou`, 1870 err: true, 1871 }, 1872 { 1873 name: "skip-bool-null-err", 1874 json: `nil`, 1875 err: true, 1876 }, 1877 } 1878 1879 for _, testCase := range testCases { 1880 t.Run(testCase.name, func(t *testing.T) { 1881 dec := NewDecoder(strings.NewReader(testCase.json)) 1882 err := dec.skipData() 1883 if testCase.err { 1884 assert.NotNil(t, err, "err should not be nil") 1885 } else { 1886 assert.Nil(t, err, "err should be nil") 1887 } 1888 }) 1889 } 1890 t.Run("error-invalid-json", func(t *testing.T) { 1891 dec := NewDecoder(strings.NewReader("")) 1892 err := dec.skipData() 1893 assert.NotNil(t, err, "err should not be nil as data is empty") 1894 assert.IsType(t, InvalidJSONError(""), err, "err should of type InvalidJSONError") 1895 }) 1896 t.Run("skip-array-error-invalid-json", func(t *testing.T) { 1897 dec := NewDecoder(strings.NewReader("")) 1898 _, err := dec.skipArray() 1899 assert.NotNil(t, err, "err should not be nil as data is empty") 1900 assert.IsType(t, InvalidJSONError(""), err, "err should of type InvalidJSONError") 1901 }) 1902 }