github.com/kamalshkeir/kencoding@v0.0.2-0.20230409043843-44b609a0475a/json/json_test.go (about) 1 package json 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "encoding" 7 "encoding/json" 8 "errors" 9 "flag" 10 "fmt" 11 "io" 12 "io/ioutil" 13 "math" 14 "os" 15 "path/filepath" 16 "reflect" 17 "runtime" 18 "strconv" 19 "strings" 20 "testing" 21 "time" 22 ) 23 24 // The encoding/json package does not export the msg field of json.SyntaxError, 25 // so we use this replacement type in tests. 26 type testSyntaxError struct { 27 msg string 28 Offset int64 29 } 30 31 func (e *testSyntaxError) Error() string { return e.msg } 32 33 var ( 34 marshal func([]byte, interface{}) ([]byte, error) 35 unmarshal func([]byte, interface{}) error 36 escapeHTML bool 37 ) 38 39 func TestMain(m *testing.M) { 40 var pkg string 41 flag.StringVar(&pkg, "package", ".", "The name of the package to test (encoding/json, or default to this package)") 42 flag.BoolVar(&escapeHTML, "escapehtml", false, "Whether to enable HTML escaping or not") 43 flag.Parse() 44 45 switch pkg { 46 case "encoding/json": 47 buf := &buffer{} 48 enc := json.NewEncoder(buf) 49 enc.SetEscapeHTML(escapeHTML) 50 51 marshal = func(b []byte, v interface{}) ([]byte, error) { 52 buf.data = b 53 err := enc.Encode(v) 54 return buf.data, err 55 } 56 57 unmarshal = json.Unmarshal 58 59 default: 60 flags := AppendFlags(0) 61 if escapeHTML { 62 flags |= EscapeHTML 63 } 64 65 marshal = func(b []byte, v interface{}) ([]byte, error) { 66 return Append(b, v, flags) 67 } 68 69 unmarshal = func(b []byte, v interface{}) error { 70 _, err := Parse(b, v, ZeroCopy) 71 return err 72 } 73 } 74 75 os.Exit(m.Run()) 76 } 77 78 type point struct { 79 X int `json:"x"` 80 Y int `json:"y"` 81 } 82 83 type tree struct { 84 Value string 85 Left *tree 86 Right *tree 87 } 88 89 var testValues = [...]interface{}{ 90 // constants 91 nil, 92 false, 93 true, 94 95 // int 96 int(0), 97 int(1), 98 int(42), 99 int(-1), 100 int(-42), 101 int8(math.MaxInt8), 102 int8(math.MinInt8), 103 int16(math.MaxInt16), 104 int16(math.MinInt16), 105 int32(math.MaxInt32), 106 int32(math.MinInt32), 107 int64(math.MaxInt64), 108 int64(math.MinInt64), 109 110 // uint 111 uint(0), 112 uint(1), 113 uintptr(0), 114 uintptr(1), 115 uint8(math.MaxUint8), 116 uint16(math.MaxUint16), 117 uint32(math.MaxUint32), 118 uint64(math.MaxUint64), 119 120 // float 121 float32(0), 122 float32(0.5), 123 float32(math.SmallestNonzeroFloat32), 124 float32(math.MaxFloat32), 125 float64(0), 126 float64(0.5), 127 float64(math.SmallestNonzeroFloat64), 128 float64(math.MaxFloat64), 129 130 // number 131 Number("0"), 132 Number("1234567890"), 133 Number("-0.5"), 134 Number("-1e+2"), 135 136 // string 137 "", 138 "Hello World!", 139 "Hello\"World!", 140 "Hello\\World!", 141 "Hello\nWorld!", 142 "Hello\rWorld!", 143 "Hello\tWorld!", 144 "Hello\bWorld!", 145 "Hello\fWorld!", 146 "你好", 147 "<", 148 ">", 149 "&", 150 "\u001944", 151 "\u00c2e>", 152 "\u00c2V?", 153 "\u000e=8", 154 "\u001944\u00c2e>\u00c2V?\u000e=8", 155 "ir\u001bQJ\u007f\u0007y\u0015)", 156 strings.Repeat("A", 32), 157 strings.Repeat("A", 250), 158 strings.Repeat("A", 1020), 159 160 // bytes 161 []byte(""), 162 []byte("Hello World!"), 163 bytes.Repeat([]byte("A"), 250), 164 bytes.Repeat([]byte("A"), 1020), 165 166 // time 167 time.Unix(0, 0).In(time.UTC), 168 time.Unix(1, 42).In(time.UTC), 169 time.Unix(17179869184, 999999999).In(time.UTC), 170 time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC), 171 172 // array 173 [...]int{}, 174 [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 175 176 // slice 177 []int{}, 178 []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 179 makeSlice(250), 180 makeSlice(1020), 181 []string{"A", "B", "C"}, 182 []interface{}{nil, true, false, 0.5, "Hello World!"}, 183 184 // map 185 makeMapStringBool(0), 186 makeMapStringBool(15), 187 makeMapStringBool(1020), 188 makeMapStringString(0), 189 makeMapStringString(15), 190 makeMapStringString(1020), 191 makeMapStringStringSlice(0), 192 makeMapStringStringSlice(15), 193 makeMapStringStringSlice(1020), 194 makeMapStringInterface(0), 195 makeMapStringInterface(15), 196 makeMapStringInterface(1020), 197 map[int]bool{1: false, 42: true}, 198 map[textValue]bool{{1, 2}: true, {3, 4}: false}, 199 map[string]*point{ 200 "A": {1, 2}, 201 "B": {3, 4}, 202 "C": {5, 6}, 203 }, 204 map[string]RawMessage{ 205 "A": RawMessage(`{}`), 206 "B": RawMessage(`null`), 207 "C": RawMessage(`42`), 208 }, 209 210 // struct 211 struct{}{}, 212 struct{ A int }{42}, 213 struct{ A, B, C int }{1, 2, 3}, 214 struct { 215 A int 216 T time.Time 217 S string 218 }{42, time.Date(2016, 12, 20, 0, 20, 1, 0, time.UTC), "Hello World!"}, 219 // These types are interesting because they fit in a pointer so the compiler 220 // puts their value directly into the pointer field of the interface{} that 221 // is passed to Marshal. 222 struct{ X *int }{}, 223 struct{ X *int }{new(int)}, 224 struct{ X **int }{}, 225 // Struct types with more than one pointer, those exercise the regular 226 // pointer handling with code that dereferences the fields. 227 struct{ X, Y *int }{}, 228 struct{ X, Y *int }{new(int), new(int)}, 229 struct { 230 A string `json:"name"` 231 B string `json:"-"` 232 C string `json:",omitempty"` 233 D map[string]interface{} `json:",string"` 234 e string 235 }{A: "Luke", D: map[string]interface{}{"answer": float64(42)}}, 236 struct{ point }{point{1, 2}}, 237 tree{ 238 Value: "T", 239 Left: &tree{Value: "L"}, 240 Right: &tree{Value: "R", Left: &tree{Value: "R-L"}}, 241 }, 242 243 // pointer 244 (*string)(nil), 245 new(int), 246 247 // Marshaler/Unmarshaler 248 jsonValue{}, 249 jsonValue{1, 2}, 250 251 // encoding.TextMarshaler/encoding.TextUnmarshaler 252 textValue{}, 253 textValue{1, 2}, 254 255 // RawMessage 256 RawMessage(`{ 257 "answer": 42, 258 "hello": "world" 259 }`), 260 261 // fixtures 262 loadTestdata(filepath.Join(runtime.GOROOT(), "src/encoding/json/testdata/code.json.gz")), 263 } 264 265 var durationTestValues = []interface{}{ 266 // duration 267 time.Nanosecond, 268 time.Microsecond, 269 time.Millisecond, 270 time.Second, 271 time.Minute, 272 time.Hour, 273 274 // struct with duration 275 struct{ D1, D2 time.Duration }{time.Millisecond, time.Hour}, 276 } 277 278 func makeSlice(n int) []int { 279 s := make([]int, n) 280 for i := range s { 281 s[i] = i 282 } 283 return s 284 } 285 286 func makeMapStringBool(n int) map[string]bool { 287 m := make(map[string]bool, n) 288 for i := 0; i != n; i++ { 289 m[strconv.Itoa(i)] = true 290 } 291 return m 292 } 293 294 func makeMapStringString(n int) map[string]string { 295 m := make(map[string]string, n) 296 for i := 0; i != n; i++ { 297 m[strconv.Itoa(i)] = fmt.Sprintf("%d Hello, world!", i) 298 } 299 return m 300 } 301 302 func makeMapStringStringSlice(n int) map[string][]string { 303 m := make(map[string][]string, n) 304 for i := 0; i != n; i++ { 305 m[strconv.Itoa(i)] = []string{strconv.Itoa(i), "Hello,", "world!"} 306 } 307 return m 308 } 309 310 func makeMapStringInterface(n int) map[string]interface{} { 311 m := make(map[string]interface{}, n) 312 for i := 0; i != n; i++ { 313 m[strconv.Itoa(i)] = nil 314 } 315 return m 316 } 317 318 func testName(v interface{}) string { 319 return fmt.Sprintf("%T", v) 320 } 321 322 type codeResponse2 struct { 323 Tree *codeNode2 `json:"tree"` 324 Username string `json:"username"` 325 } 326 327 type codeNode2 struct { 328 Name string `json:"name"` 329 Kids []*codeNode `json:"kids"` 330 CLWeight float64 `json:"cl_weight"` 331 Touches int `json:"touches"` 332 MinT int64 `json:"min_t"` 333 MaxT int64 `json:"max_t"` 334 MeanT int64 `json:"mean_t"` 335 } 336 337 func loadTestdata(path string) interface{} { 338 f, err := os.Open(path) 339 if err != nil { 340 return err.Error() 341 } 342 defer f.Close() 343 344 r, err := gzip.NewReader(f) 345 if err != nil { 346 return err.Error() 347 } 348 defer r.Close() 349 350 testdata := new(codeResponse2) 351 if err := json.NewDecoder(r).Decode(testdata); err != nil { 352 return err.Error() 353 } 354 return testdata 355 } 356 357 func TestCodec(t *testing.T) { 358 for _, v1 := range testValues { 359 t.Run(testName(v1), func(t *testing.T) { 360 v2 := newValue(v1) 361 362 a, err := json.MarshalIndent(v1, "", "\t") 363 if err != nil { 364 t.Error(err) 365 return 366 } 367 a = append(a, '\n') 368 369 buf := &bytes.Buffer{} 370 enc := NewEncoder(buf) 371 enc.SetIndent("", "\t") 372 373 if err := enc.Encode(v1); err != nil { 374 t.Error(err) 375 return 376 } 377 b := buf.Bytes() 378 379 if !Valid(b) { 380 t.Error("invalid JSON representation") 381 } 382 383 if !bytes.Equal(a, b) { 384 t.Error("JSON representations mismatch") 385 t.Log("expected:", string(a)) 386 t.Log("found: ", string(b)) 387 } 388 389 dec := NewDecoder(bytes.NewBuffer(b)) 390 391 if err := dec.Decode(v2.Interface()); err != nil { 392 t.Errorf("%T: %v", err, err) 393 return 394 } 395 396 x1 := v1 397 x2 := v2.Elem().Interface() 398 399 if !reflect.DeepEqual(x1, x2) { 400 t.Error("values mismatch") 401 t.Logf("expected: %#v", x1) 402 t.Logf("found: %#v", x2) 403 } 404 405 if b, err := ioutil.ReadAll(dec.Buffered()); err != nil { 406 t.Error(err) 407 } else if len(b) != 0 { 408 t.Errorf("leftover trailing bytes in the decoder: %q", b) 409 } 410 }) 411 } 412 } 413 414 // TestCodecDuration isolates testing of time.Duration. The stdlib un/marshals 415 // this type as integers whereas this library un/marshals formatted string 416 // values. Therefore, plugging durations into TestCodec would cause fail since 417 // it checks equality on the marshaled strings from the two libraries. 418 func TestCodecDuration(t *testing.T) { 419 for _, v1 := range durationTestValues { 420 t.Run(testName(v1), func(t *testing.T) { 421 v2 := newValue(v1) 422 423 // encode using stdlib. (will be an int) 424 std, err := json.MarshalIndent(v1, "", "\t") 425 if err != nil { 426 t.Error(err) 427 return 428 } 429 std = append(std, '\n') 430 431 // decode using our decoder. (reads int to duration) 432 dec := NewDecoder(bytes.NewBuffer([]byte(std))) 433 434 if err := dec.Decode(v2.Interface()); err != nil { 435 t.Errorf("%T: %v", err, err) 436 return 437 } 438 439 x1 := v1 440 x2 := v2.Elem().Interface() 441 442 if !reflect.DeepEqual(x1, x2) { 443 t.Error("values mismatch") 444 t.Logf("expected: %#v", x1) 445 t.Logf("found: %#v", x2) 446 } 447 448 // encoding using our encoder. (writes duration as string) 449 buf := &bytes.Buffer{} 450 enc := NewEncoder(buf) 451 enc.SetIndent("", "\t") 452 453 if err := enc.Encode(v1); err != nil { 454 t.Error(err) 455 return 456 } 457 b := buf.Bytes() 458 459 if !Valid(b) { 460 t.Error("invalid JSON representation") 461 } 462 463 if reflect.DeepEqual(std, b) { 464 t.Error("encoded durations should not match stdlib") 465 t.Logf("got: %s", b) 466 } 467 468 // decode using our decoder. (reads string to duration) 469 dec = NewDecoder(bytes.NewBuffer([]byte(std))) 470 471 if err := dec.Decode(v2.Interface()); err != nil { 472 t.Errorf("%T: %v", err, err) 473 return 474 } 475 476 x1 = v1 477 x2 = v2.Elem().Interface() 478 479 if !reflect.DeepEqual(x1, x2) { 480 t.Error("values mismatch") 481 t.Logf("expected: %#v", x1) 482 t.Logf("found: %#v", x2) 483 } 484 }) 485 } 486 } 487 488 func newValue(model interface{}) reflect.Value { 489 if model == nil { 490 return reflect.New(reflect.TypeOf(&model).Elem()) 491 } 492 return reflect.New(reflect.TypeOf(model)) 493 } 494 495 func BenchmarkMarshal(b *testing.B) { 496 j := make([]byte, 0, 128*1024) 497 498 for _, v := range testValues { 499 b.Run(testName(v), func(b *testing.B) { 500 if marshal == nil { 501 return 502 } 503 504 for i := 0; i != b.N; i++ { 505 j, _ = marshal(j[:0], v) 506 } 507 508 b.SetBytes(int64(len(j))) 509 }) 510 } 511 } 512 513 func BenchmarkUnmarshal(b *testing.B) { 514 for _, v := range testValues { 515 b.Run(testName(v), func(b *testing.B) { 516 if unmarshal == nil { 517 return 518 } 519 520 x := v 521 if d, ok := x.(time.Duration); ok { 522 x = duration(d) 523 } 524 525 j, _ := json.Marshal(x) 526 x = newValue(v).Interface() 527 528 for i := 0; i != b.N; i++ { 529 unmarshal(j, x) 530 } 531 532 b.SetBytes(int64(len(j))) 533 }) 534 } 535 } 536 537 type buffer struct{ data []byte } 538 539 func (buf *buffer) Write(b []byte) (int, error) { 540 buf.data = append(buf.data, b...) 541 return len(b), nil 542 } 543 544 func (buf *buffer) WriteString(s string) (int, error) { 545 buf.data = append(buf.data, s...) 546 return len(s), nil 547 } 548 549 type jsonValue struct { 550 x int32 551 y int32 552 } 553 554 func (v jsonValue) MarshalJSON() ([]byte, error) { 555 return Marshal([2]int32{v.x, v.y}) 556 } 557 558 func (v *jsonValue) UnmarshalJSON(b []byte) error { 559 var a [2]int32 560 err := Unmarshal(b, &a) 561 v.x = a[0] 562 v.y = a[1] 563 return err 564 } 565 566 type textValue struct { 567 x int32 568 y int32 569 } 570 571 func (v textValue) MarshalText() ([]byte, error) { 572 return []byte(fmt.Sprintf("(%d,%d)", v.x, v.y)), nil 573 } 574 575 func (v *textValue) UnmarshalText(b []byte) error { 576 _, err := fmt.Sscanf(string(b), "(%d,%d)", &v.x, &v.y) 577 return err 578 } 579 580 type duration time.Duration 581 582 func (d duration) MarshalJSON() ([]byte, error) { 583 return []byte(`"` + time.Duration(d).String() + `"`), nil 584 } 585 586 func (d *duration) UnmarshalJSON(b []byte) error { 587 var s string 588 if err := json.Unmarshal(b, &s); err != nil { 589 return err 590 } 591 x, err := time.ParseDuration(s) 592 *d = duration(x) 593 return err 594 } 595 596 var ( 597 _ Marshaler = jsonValue{} 598 _ Marshaler = duration(0) 599 600 _ encoding.TextMarshaler = textValue{} 601 602 _ Unmarshaler = (*jsonValue)(nil) 603 _ Unmarshaler = (*duration)(nil) 604 605 _ encoding.TextUnmarshaler = (*textValue)(nil) 606 ) 607 608 func TestDecodeStructFieldCaseInsensitive(t *testing.T) { 609 b := []byte(`{ "type": "changed" }`) 610 s := struct { 611 Type string 612 }{"unchanged"} 613 614 if err := Unmarshal(b, &s); err != nil { 615 t.Error(err) 616 } 617 618 if s.Type != "changed" { 619 t.Error("s.Type: expected to be changed but found", s.Type) 620 } 621 } 622 623 func TestDecodeLines(t *testing.T) { 624 tests := []struct { 625 desc string 626 reader io.Reader 627 expectCount int 628 }{ 629 630 // simple 631 632 { 633 desc: "bare object", 634 reader: strings.NewReader("{\"Good\":true}"), 635 expectCount: 1, 636 }, 637 { 638 desc: "multiple objects on one line", 639 reader: strings.NewReader("{\"Good\":true}{\"Good\":true}\n"), 640 expectCount: 2, 641 }, 642 { 643 desc: "object spanning multiple lines", 644 reader: strings.NewReader("{\n\"Good\":true\n}\n"), 645 expectCount: 1, 646 }, 647 648 // whitespace handling 649 650 { 651 desc: "trailing newline", 652 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n"), 653 expectCount: 2, 654 }, 655 { 656 desc: "multiple trailing newlines", 657 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}\n\n"), 658 expectCount: 2, 659 }, 660 { 661 desc: "blank lines", 662 reader: strings.NewReader("{\"Good\":true}\n\n{\"Good\":true}"), 663 expectCount: 2, 664 }, 665 { 666 desc: "no trailing newline", 667 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":true}"), 668 expectCount: 2, 669 }, 670 { 671 desc: "leading whitespace", 672 reader: strings.NewReader(" {\"Good\":true}\n\t{\"Good\":true}"), 673 expectCount: 2, 674 }, 675 676 // multiple reads 677 678 { 679 desc: "one object, multiple reads", 680 reader: io.MultiReader( 681 strings.NewReader("{"), 682 strings.NewReader("\"Good\": true"), 683 strings.NewReader("}\n"), 684 ), 685 expectCount: 1, 686 }, 687 688 // EOF reads 689 690 { 691 desc: "one object + EOF", 692 reader: &eofReader{"{\"Good\":true}\n"}, 693 expectCount: 1, 694 }, 695 { 696 desc: "leading whitespace + EOF", 697 reader: &eofReader{"\n{\"Good\":true}\n"}, 698 expectCount: 1, 699 }, 700 { 701 desc: "multiple objects + EOF", 702 reader: &eofReader{"{\"Good\":true}\n{\"Good\":true}\n"}, 703 expectCount: 2, 704 }, 705 { 706 desc: "one object + multiple reads + EOF", 707 reader: io.MultiReader( 708 strings.NewReader("{"), 709 strings.NewReader(" \"Good\": true"), 710 &eofReader{"}\n"}, 711 ), 712 expectCount: 1, 713 }, 714 { 715 desc: "multiple objects + multiple reads + EOF", 716 reader: io.MultiReader( 717 strings.NewReader("{"), 718 strings.NewReader(" \"Good\": true}{\"Good\": true}"), 719 &eofReader{"\n"}, 720 ), 721 expectCount: 2, 722 }, 723 724 { 725 // the 2nd object should be discarded, as 42 cannot be cast to bool 726 desc: "unmarshal error while decoding", 727 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n{\"Good\":true}\n"), 728 expectCount: 2, 729 }, 730 { 731 // the 2nd object should be discarded, as 42 cannot be cast to bool 732 desc: "unmarshal error while decoding last object", 733 reader: strings.NewReader("{\"Good\":true}\n{\"Good\":42}\n"), 734 expectCount: 1, 735 }, 736 } 737 738 type obj struct { 739 Good bool 740 } 741 742 for _, test := range tests { 743 t.Run(test.desc, func(t *testing.T) { 744 d := NewDecoder(test.reader) 745 var count int 746 var err error 747 for { 748 var o obj 749 err = d.Decode(&o) 750 if err != nil { 751 if err == io.EOF { 752 break 753 } 754 755 switch err.(type) { 756 case *SyntaxError, *UnmarshalTypeError, *UnmarshalFieldError: 757 t.Log("unmarshal error", err) 758 continue 759 } 760 761 t.Error("decode error", err) 762 break 763 } 764 if !o.Good { 765 t.Errorf("object was not unmarshaled correctly: %#v", o) 766 } 767 count++ 768 } 769 770 if err != nil && err != io.EOF { 771 t.Error(err) 772 } 773 774 if count != test.expectCount { 775 t.Errorf("expected %d objects, got %d", test.expectCount, count) 776 } 777 }) 778 } 779 } 780 781 // eofReader is a simple io.Reader that reads its full contents _and_ returns 782 // and EOF in the first call. Subsequent Read calls only return EOF. 783 type eofReader struct { 784 s string 785 } 786 787 func (r *eofReader) Read(p []byte) (n int, err error) { 788 n = copy(p, r.s) 789 r.s = r.s[n:] 790 if r.s == "" { 791 err = io.EOF 792 } 793 return 794 } 795 796 func TestDontMatchCaseIncensitiveStructFields(t *testing.T) { 797 b := []byte(`{ "type": "changed" }`) 798 s := struct { 799 Type string 800 }{"unchanged"} 801 802 if _, err := Parse(b, &s, DontMatchCaseInsensitiveStructFields); err != nil { 803 t.Error(err) 804 } 805 806 if s.Type != "unchanged" { 807 t.Error("s.Type: expected to be unchanged but found", s.Type) 808 } 809 } 810 811 func TestMarshalFuzzBugs(t *testing.T) { 812 tests := []struct { 813 value interface{} 814 output string 815 }{ 816 { // html sequences are escaped even in RawMessage 817 value: struct { 818 P RawMessage 819 }{P: RawMessage(`"<"`)}, 820 output: "{\"P\":\"\\u003c\"}", 821 }, 822 { // raw message output is compacted 823 value: struct { 824 P RawMessage 825 }{P: RawMessage(`{"" :{}}`)}, 826 output: "{\"P\":{\"\":{}}}", 827 }, 828 } 829 830 for _, test := range tests { 831 t.Run("", func(t *testing.T) { 832 b, err := Marshal(test.value) 833 if err != nil { 834 t.Fatal(err) 835 } 836 837 if string(b) != test.output { 838 t.Error("values mismatch") 839 t.Logf("expected: %#v", test.output) 840 t.Logf("found: %#v", string(b)) 841 } 842 }) 843 } 844 } 845 846 func TestUnmarshalFuzzBugs(t *testing.T) { 847 tests := []struct { 848 input string 849 value interface{} 850 }{ 851 { // non-UTF8 sequences must be converted to the utf8.RuneError character. 852 input: "[\"00000\xef\"]", 853 value: []interface{}{"00000�"}, 854 }, 855 { // UTF16 surrogate followed by null character 856 input: "[\"\\ud800\\u0000\"]", 857 value: []interface{}{"�\x00"}, 858 }, 859 { // UTF16 surrogate followed by ascii character 860 input: "[\"\\uDF00\\u000e\"]", 861 value: []interface{}{"�\x0e"}, 862 }, 863 { // UTF16 surrogate followed by unicode character 864 input: "[[\"\\uDF00\\u0800\"]]", 865 value: []interface{}{[]interface{}{"�ࠀ"}}, 866 }, 867 { // invalid UTF16 surrogate sequenced followed by a valid UTF16 surrogate sequence 868 input: "[\"\\udf00\\udb00\\udf00\"]", 869 value: []interface{}{"�\U000d0300"}, 870 }, 871 { // decode single-element slice into []byte field 872 input: "{\"f\":[0],\"0\":[0]}", 873 value: struct{ F []byte }{F: []byte{0}}, 874 }, 875 { // decode multi-element slice into []byte field 876 input: "{\"F\":[3,1,1,1,9,9]}", 877 value: struct{ F []byte }{F: []byte{3, 1, 1, 1, 9, 9}}, 878 }, 879 { // decode string with escape sequence into []byte field 880 input: "{\"F\":\"0p00\\r\"}", 881 value: struct{ F []byte }{F: []byte("ҝ4")}, 882 }, 883 { // decode unicode code points which fold into ascii characters 884 input: "{\"ſ\":\"8\"}", 885 value: struct { 886 S int `json:",string"` 887 }{S: 8}, 888 }, 889 { // decode unicode code points which don't fold into ascii characters 890 input: "{\"İ\":\"\"}", 891 value: struct{ I map[string]string }{I: nil}, 892 }, 893 { // override pointer-to-pointer field clears the inner pointer only 894 input: "{\"o\":0,\"o\":null}", 895 value: struct{ O **int }{O: new(*int)}, 896 }, 897 { // subsequent occurrences of a map field retain keys previously loaded 898 input: "{\"i\":{\"\":null},\"i\":{}}", 899 value: struct{ I map[string]string }{I: map[string]string{"": ""}}, 900 }, 901 { // an empty string is an invalid JSON input 902 input: "", 903 }, 904 { // ASCII character below 0x20 are invalid JSON input 905 input: "[\"\b\"]", 906 }, 907 { // random byte before any value 908 input: "\xad", 909 }, 910 { // cloud be the beginning of a false value but not 911 input: "f", 912 value: false, 913 }, 914 { // random ASCII character 915 input: "}", 916 value: []interface{}{}, 917 }, 918 { // random byte after valid JSON, decoded to a nil type 919 input: "0\x93", 920 }, 921 { // random byte after valid JSON, decoded to a int type 922 input: "0\x93", 923 value: 0, 924 }, 925 { // random byte after valid JSON, decoded to a slice type 926 input: "0\x93", 927 value: []interface{}{}, 928 }, 929 { // decode integer into slice 930 input: "0", 931 value: []interface{}{}, 932 }, 933 { // decode integer with trailing space into slice 934 input: "0\t", 935 value: []interface{}{}, 936 }, 937 { // decode integer with leading random bytes into slice 938 input: "\b0", 939 value: []interface{}{}, 940 }, 941 { // decode string into slice followed by number 942 input: "\"\"0", 943 value: []interface{}{}, 944 }, 945 { // decode what looks like an object followed by a number into a string 946 input: "{0", 947 value: "", 948 }, 949 { // decode what looks like an object followed by a number into a map 950 input: "{0", 951 value: map[string]string{}, 952 }, 953 { // decode string into string with trailing random byte 954 input: "\"\"\f", 955 value: "", 956 }, 957 { // decode weird number value into nil 958 input: "-00", 959 }, 960 { // decode an invalid escaped sequence 961 input: "\"\\0\"", 962 value: "", 963 }, 964 { // decode what looks like an array followed by a number into a slice 965 input: "[9E600", 966 value: []interface{}{}, 967 }, 968 { // decode a number which is too large to fit in a float64 969 input: "[1e900]", 970 value: []interface{}{}, 971 }, 972 { // many nested arrays openings 973 input: "[[[[[[", 974 value: []interface{}{}, 975 }, 976 { // decode a map with value type mismatch and missing closing character 977 input: "{\"\":0", 978 value: map[string]string{}, 979 }, 980 { // decode a struct with value type mismatch and missing closing character 981 input: "{\"E\":\"\"", 982 value: struct{ E uint8 }{}, 983 }, 984 { // decode a map with value type mismatch 985 input: "{\"\":0}", 986 value: map[string]string{}, 987 }, 988 { // decode number with exponent into integer field 989 input: "{\"e\":0e0}", 990 value: struct{ E uint8 }{}, 991 }, 992 { // decode invalid integer representation into integer field 993 input: "{\"e\":00}", 994 value: struct{ E uint8 }{}, 995 }, 996 { // decode unterminated array into byte slice 997 input: "{\"F\":[", 998 value: struct{ F []byte }{}, 999 }, 1000 { // attempt to decode string into in 1001 input: "{\"S\":\"\"}", 1002 value: struct { 1003 S int `json:",string"` 1004 }{}, 1005 }, 1006 { // decode object with null key into map 1007 input: "{null:0}", 1008 value: map[string]interface{}{}, 1009 }, 1010 { // decode unquoted integer into struct field with string tag 1011 input: "{\"S\":0}", 1012 value: struct { 1013 S int `json:",string"` 1014 }{}, 1015 }, 1016 { // invalid base64 content when decoding string into byte slice 1017 input: "{\"F\":\"0\"}", 1018 value: struct{ F []byte }{}, 1019 }, 1020 { // decode an object with a "null" string as key 1021 input: "{\"null\":null}", 1022 value: struct { 1023 S int `json:",string"` 1024 }{}, 1025 }, 1026 { // decode an invalid floating point number representation into an integer field with string tag 1027 input: "{\"s\":8e800}", 1028 value: struct { 1029 S int `json:",string"` 1030 }{}, 1031 }, 1032 { // decode a string with leading zeroes into an integer field with string tag 1033 input: "{\"S\":\"00\"}", 1034 value: struct { 1035 S int `json:",string"` 1036 }{}, 1037 }, 1038 { // decode a string with invalid leading sign and zeroes into an integer field with string tag 1039 input: "{\"S\":\"+00\"}", 1040 value: struct { 1041 S int `json:",string"` 1042 }{}, 1043 }, 1044 { // decode a string with valid leading sign and zeroes into an integer field with string tag 1045 input: "{\"S\":\"-00\"}", 1046 value: struct { 1047 S int `json:",string"` 1048 }{}, 1049 }, 1050 { // decode non-ascii string into integer field with string tag 1051 input: "{\"ſ\":\"\xbf\"}", 1052 value: struct { 1053 S int `json:",string"` 1054 }{}, 1055 }, 1056 { // decode a valid floating point number representation into an integer field with string tag 1057 input: "{\"S\":0.0}", 1058 value: struct { 1059 S int `json:",string"` 1060 }{}, 1061 }, 1062 { // decode string with invalid leading sign to integer field with string tag 1063 input: "{\"S\":\"+0\"}", 1064 value: struct { 1065 S int `json:",string"` 1066 }{}, 1067 }, 1068 { // decode string with valid leading sign to integer field with string tag 1069 input: "{\"S\":\"-0\"}", 1070 value: struct { 1071 S int `json:",string"` 1072 }{}, 1073 }, 1074 { // decode string with object representation to integer field with string tag 1075 input: "{\"s\":{}}", 1076 value: struct { 1077 S int `json:",string"` 1078 }{}, 1079 }, 1080 { // decoding integer with leading zeroes 1081 input: "{\"o\":00}", 1082 value: struct{ O **int }{}, 1083 }, 1084 { // codeding string with invalid float representation into integer field with string tag 1085 input: "{\"s\":\"0.\"}", 1086 value: struct { 1087 S int `json:",string"` 1088 }{}, 1089 }, 1090 { // malformed negative integer in object value 1091 input: "{\"N\":-00}", 1092 value: struct{ N *int }{}, 1093 }, 1094 { // integer overflow 1095 input: "{\"a\":9223372036854775808}", 1096 value: struct { 1097 A int `json:",omitempty"` 1098 }{}, 1099 }, 1100 { // decode string with number followed by random byte into integer field with string tag 1101 input: "{\"s\":\"0]\"}", 1102 value: struct { 1103 S int `json:",string"` 1104 }{}, 1105 }, 1106 { // decode object into integer field 1107 input: "{\"n\":{}}", 1108 value: struct{ N *int }{}, 1109 }, 1110 { // decode negative integer into unsigned type 1111 input: "{\"E\":-0}", 1112 value: struct{ E uint8 }{}, 1113 }, 1114 { // decode string with number followed by random byte into integer field with string tag 1115 input: "{\"s\":\"03�\"}", 1116 value: struct { 1117 S int `json:",string"` 1118 }{}, 1119 }, 1120 { // decode string with leading zeroes into integer field with string tag 1121 input: "{\"s\":\"03\"}", 1122 value: struct { 1123 S int `json:",string"` 1124 }{S: 3}, 1125 }, 1126 { // decode string containing what looks like an object into integer field with string tag 1127 input: "{\"S\":\"{}\"}", 1128 value: struct { 1129 S int `json:",string"` 1130 }{}, 1131 }, 1132 { // decode an empty string followed by the same field with a null value into a byte slice 1133 input: "{\"F\":\"\",\"F\":null}", 1134 value: struct{ F []byte }{}, 1135 }, 1136 { // decode string containing a float into an integer field with string tag 1137 input: "{\"S\":\"0e0\"}", 1138 value: struct { 1139 S int `json:",string"` 1140 }{}, 1141 }, 1142 { // decode string with negative sign into a an integer field with string tag 1143 input: "{\"s\":\"-\"}", 1144 value: struct { 1145 S int `json:",string"` 1146 }{}, 1147 }, 1148 { // decode string with positive sign into a an integer field with string tag 1149 input: "{\"s\":\"+\"}", 1150 value: struct { 1151 S int `json:",string"` 1152 }{}, 1153 }, 1154 { // decode an integer into a json unmarshaler 1155 input: "{\"q\":0}", 1156 value: struct { 1157 Q testMarshaller 1158 }{}, 1159 }, 1160 // This test fails because it appears that the encoding/json package 1161 // will decode "q" before "s", so it returns an error about "q" being of 1162 // the wrong type while this package will prase object keys in the order 1163 // that they appear in the JSON input, so it detects the error from "s" 1164 // first. 1165 // 1166 //{ 1167 // input: "{\"s\":0,\"q\":0}", 1168 // value: struct { 1169 // Q testMarshaller 1170 // S int `json:",string"` 1171 // }{}, 1172 //}, 1173 } 1174 1175 for _, test := range tests { 1176 t.Run("", func(t *testing.T) { 1177 var ptr1 interface{} 1178 var ptr2 interface{} 1179 1180 if test.value != nil { 1181 ptr1 = reflect.New(reflect.TypeOf(test.value)).Interface() 1182 ptr2 = reflect.New(reflect.TypeOf(test.value)).Interface() 1183 } 1184 1185 err1 := json.Unmarshal([]byte(test.input), ptr1) 1186 err2 := Unmarshal([]byte(test.input), ptr2) 1187 1188 if reflect.TypeOf(err1) != reflect.TypeOf(err2) { 1189 t.Error("errors mismatch") 1190 t.Logf("expected: %T: %v", err1, err1) 1191 t.Logf("found: %T: %v", err2, err2) 1192 } else if err1 == nil && test.value != nil { 1193 if value := reflect.ValueOf(ptr2).Elem().Interface(); !reflect.DeepEqual(test.value, value) { 1194 t.Error("values mismatch") 1195 t.Logf("expected: %#v", test.value) 1196 t.Logf("found: %#v", value) 1197 } 1198 } 1199 }) 1200 } 1201 } 1202 1203 func BenchmarkEasyjsonUnmarshalSmallStruct(b *testing.B) { 1204 type Hashtag struct { 1205 Indices []int `json:"indices"` 1206 Text string `json:"text"` 1207 } 1208 1209 //easyjson:json 1210 type Entities struct { 1211 Hashtags []Hashtag `json:"hashtags"` 1212 Urls []*string `json:"urls"` 1213 UserMentions []*string `json:"user_mentions"` 1214 } 1215 1216 var json = []byte(`{"hashtags":[{"indices":[5, 10],"text":"some-text"}],"urls":[],"user_mentions":[]}`) 1217 1218 for i := 0; i < b.N; i++ { 1219 var value Entities 1220 if err := Unmarshal(json, &value); err != nil { 1221 b.Fatal(err) 1222 } 1223 } 1224 } 1225 1226 type testMarshaller struct { 1227 v string 1228 } 1229 1230 func (m *testMarshaller) MarshalJSON() ([]byte, error) { 1231 return Marshal(m.v) 1232 } 1233 1234 func (m *testMarshaller) UnmarshalJSON(data []byte) error { 1235 return Unmarshal(data, &m.v) 1236 } 1237 1238 func TestGithubIssue11(t *testing.T) { 1239 // https://github.com/kamalshkeir/kencoding/issues/11 1240 v := struct{ F float64 }{ 1241 F: math.NaN(), 1242 } 1243 1244 _, err := Marshal(v) 1245 if err == nil { 1246 t.Error("no error returned when marshalling NaN value") 1247 } else if s := err.Error(); !strings.Contains(s, "NaN") { 1248 t.Error("error returned when marshalling NaN value does not mention 'NaN':", s) 1249 } else { 1250 t.Log(s) 1251 } 1252 } 1253 1254 type Issue13 struct { 1255 Stringer fmt.Stringer 1256 Field int `json:"MyInt"` 1257 } 1258 1259 type S string 1260 1261 func (s S) String() string { return string(s) } 1262 1263 func TestGithubIssue13(t *testing.T) { 1264 // https://github.com/kamalshkeir/kencoding/issues/13 1265 v := Issue13{} 1266 1267 b, err := Marshal(v) 1268 if err != nil { 1269 t.Error("unexpected errror:", err) 1270 } else { 1271 t.Log(string(b)) 1272 } 1273 1274 v = Issue13{Stringer: S("")} 1275 if err := Unmarshal([]byte(`{"Stringer":null}`), &v); err != nil { 1276 t.Error("unexpected error:", err) 1277 } 1278 if v.Stringer != nil { 1279 t.Error("Stringer field was not overwritten") 1280 } 1281 1282 v = Issue13{} 1283 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1284 t.Error("expected error but decoding string value into nil fmt.Stringer but got <nil>") 1285 } 1286 1287 v = Issue13{Stringer: S("")} 1288 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err == nil { 1289 t.Error("expected error but decoding string value into non-pointer fmt.Stringer but got <nil>") 1290 } 1291 1292 s := S("") 1293 v = Issue13{Stringer: &s} 1294 if err := Unmarshal([]byte(`{"Stringer":"whatever"}`), &v); err != nil { 1295 t.Error("unexpected error decoding string value into pointer fmt.Stringer:", err) 1296 } 1297 } 1298 1299 func TestGithubIssue15(t *testing.T) { 1300 // https://github.com/kamalshkeir/kencoding/issues/15 1301 tests := []struct { 1302 m interface{} 1303 s string 1304 }{ 1305 { 1306 m: map[uint]bool{1: true, 123: true, 333: true, 42: true}, 1307 s: `{"1":true,"123":true,"333":true,"42":true}`, 1308 }, 1309 { 1310 m: map[int]bool{-1: true, -123: true, 333: true, 42: true}, 1311 s: `{"-1":true,"-123":true,"333":true,"42":true}`, 1312 }, 1313 } 1314 1315 for _, test := range tests { 1316 b, _ := Marshal(test.m) 1317 1318 if string(b) != test.s { 1319 t.Error("map with integer keys must be ordered by their string representation, got", string(b)) 1320 } 1321 1322 } 1323 } 1324 1325 type sliceA []byte 1326 1327 func (sliceA) MarshalJSON() ([]byte, error) { 1328 return []byte(`"A"`), nil 1329 } 1330 1331 type sliceB []byte 1332 1333 func (sliceB) MarshalText() ([]byte, error) { 1334 return []byte("B"), nil 1335 } 1336 1337 type mapA map[string]string 1338 1339 func (mapA) MarshalJSON() ([]byte, error) { 1340 return []byte(`"A"`), nil 1341 } 1342 1343 type mapB map[string]string 1344 1345 func (mapB) MarshalText() ([]byte, error) { 1346 return []byte("B"), nil 1347 } 1348 1349 type intPtrA int 1350 1351 func (*intPtrA) MarshalJSON() ([]byte, error) { 1352 return []byte(`"A"`), nil 1353 } 1354 1355 type intPtrB int 1356 1357 func (*intPtrB) MarshalText() ([]byte, error) { 1358 return []byte("B"), nil 1359 } 1360 1361 type structA struct{ I intPtrA } 1362 type structB struct{ I intPtrB } 1363 type structC struct{ M Marshaler } 1364 type structD struct{ M encoding.TextMarshaler } 1365 1366 func TestGithubIssue16(t *testing.T) { 1367 // https://github.com/kamalshkeir/kencoding/issues/16 1368 tests := []struct { 1369 value interface{} 1370 output string 1371 }{ 1372 {value: sliceA(nil), output: `"A"`}, 1373 {value: sliceB(nil), output: `"B"`}, 1374 {value: mapA(nil), output: `"A"`}, 1375 {value: mapB(nil), output: `"B"`}, 1376 {value: intPtrA(1), output: `1`}, 1377 {value: intPtrB(2), output: `2`}, 1378 {value: new(intPtrA), output: `"A"`}, 1379 {value: new(intPtrB), output: `"B"`}, 1380 {value: (*intPtrA)(nil), output: `null`}, 1381 {value: (*intPtrB)(nil), output: `null`}, 1382 {value: structA{I: 1}, output: `{"I":1}`}, 1383 {value: structB{I: 2}, output: `{"I":2}`}, 1384 {value: structC{}, output: `{"M":null}`}, 1385 {value: structD{}, output: `{"M":null}`}, 1386 {value: &structA{I: 1}, output: `{"I":"A"}`}, 1387 {value: &structB{I: 2}, output: `{"I":"B"}`}, 1388 {value: &structC{}, output: `{"M":null}`}, 1389 {value: &structD{}, output: `{"M":null}`}, 1390 } 1391 1392 for _, test := range tests { 1393 t.Run(fmt.Sprintf("%T", test.value), func(t *testing.T) { 1394 if b, _ := Marshal(test.value); string(b) != test.output { 1395 t.Errorf(`%s != %s`, string(b), test.output) 1396 } 1397 }) 1398 } 1399 } 1400 1401 func TestDecoderInputOffset(t *testing.T) { 1402 checkOffset := func(o, expected int64) { 1403 if o != expected { 1404 t.Error("unexpected input offset", o, expected) 1405 } 1406 } 1407 1408 b := []byte(`{"userId": "blah"}{"userId": "blah"} 1409 {"userId": "blah"}{"num": 0}`) 1410 d := NewDecoder(bytes.NewReader(b)) 1411 1412 var expected int64 1413 checkOffset(d.InputOffset(), expected) 1414 1415 var a struct { 1416 UserId string `json:"userId"` 1417 } 1418 1419 if err := d.Decode(&a); err != nil { 1420 t.Error("unexpected decode error", err) 1421 } 1422 expected = int64(18) 1423 checkOffset(d.InputOffset(), expected) 1424 1425 if err := d.Decode(&a); err != nil { 1426 t.Error("unexpected decode error", err) 1427 } 1428 expected = int64(38) 1429 checkOffset(d.InputOffset(), expected) 1430 1431 if err := d.Decode(&a); err != nil { 1432 t.Error("unexpected decode error", err) 1433 } 1434 expected = int64(56) 1435 checkOffset(d.InputOffset(), expected) 1436 1437 var z struct { 1438 Num int64 `json:"num"` 1439 } 1440 if err := d.Decode(&z); err != nil { 1441 t.Error("unexpected decode error", err) 1442 } 1443 expected = int64(66) 1444 checkOffset(d.InputOffset(), expected) 1445 } 1446 1447 func TestGithubIssue18(t *testing.T) { 1448 // https://github.com/kamalshkeir/kencoding/issues/18 1449 b := []byte(`{ 1450 "userId": "blah", 1451 }`) 1452 1453 d := NewDecoder(bytes.NewReader(b)) 1454 1455 var a struct { 1456 UserId string `json:"userId"` 1457 } 1458 switch err := d.Decode(&a).(type) { 1459 case *SyntaxError: 1460 default: 1461 t.Error("expected syntax error but found:", err) 1462 } 1463 1464 for i := 1; i <= 18; i++ { // up to the invalid ',' character 1465 d := NewDecoder(bytes.NewReader(b[:i])) // cut somewhere in the middle 1466 switch err := d.Decode(&a); err { 1467 case io.ErrUnexpectedEOF: 1468 default: 1469 t.Error("expected 'unexpected EOF' error but found:", err) 1470 } 1471 } 1472 } 1473 1474 func TestGithubIssue23(t *testing.T) { 1475 t.Run("marshal-1", func(t *testing.T) { 1476 type d struct{ S map[string]string } 1477 1478 b, _ := Marshal(map[string]d{"1": {S: map[string]string{"2": "3"}}}) 1479 if string(b) != `{"1":{"S":{"2":"3"}}}` { 1480 t.Error(string(b)) 1481 } 1482 }) 1483 1484 t.Run("marshal-2", func(t *testing.T) { 1485 type testInner struct { 1486 InnerMap map[string]string `json:"inner_map"` 1487 } 1488 1489 type testOuter struct { 1490 OuterMap map[string]testInner `json:"outer_map"` 1491 } 1492 1493 b, _ := Marshal(testOuter{ 1494 OuterMap: map[string]testInner{ 1495 "outer": { 1496 InnerMap: map[string]string{"inner": "value"}, 1497 }, 1498 }, 1499 }) 1500 1501 if string(b) != `{"outer_map":{"outer":{"inner_map":{"inner":"value"}}}}` { 1502 t.Error(string(b)) 1503 } 1504 }) 1505 1506 t.Run("marshal-3", func(t *testing.T) { 1507 type A struct{ A map[string]string } 1508 type B struct{ B map[string]A } 1509 type C struct{ C map[string]B } 1510 1511 b, _ := Marshal(C{ 1512 C: map[string]B{ 1513 "1": B{ 1514 B: map[string]A{ 1515 "2": A{ 1516 A: map[string]string{"3": "!"}, 1517 }, 1518 }, 1519 }, 1520 }, 1521 }) 1522 1523 if string(b) != `{"C":{"1":{"B":{"2":{"A":{"3":"!"}}}}}}` { 1524 t.Error(string(b)) 1525 } 1526 }) 1527 1528 t.Run("unmarshal-1", func(t *testing.T) { 1529 var d struct{ S map[string]string } 1530 1531 if err := Unmarshal([]byte(`{"1":{"S":{"2":"3"}}}`), &d); err != nil { 1532 t.Error(err) 1533 } 1534 }) 1535 } 1536 1537 func TestGithubIssue26(t *testing.T) { 1538 type interfaceType interface{} 1539 1540 var value interfaceType 1541 var data = []byte(`{}`) 1542 1543 if err := Unmarshal(data, &value); err != nil { 1544 t.Error(err) 1545 } 1546 } 1547 1548 func TestGithubIssue28(t *testing.T) { 1549 type A struct { 1550 Err error `json:"err"` 1551 } 1552 1553 if b, err := Marshal(&A{Err: errors.New("ABC")}); err != nil { 1554 t.Error(err) 1555 } else if string(b) != `{"err":{}}` { 1556 t.Error(string(b)) 1557 } 1558 1559 } 1560 1561 func TestGithubIssue41(t *testing.T) { 1562 expectedString := `{"Zero":0,"Three":3}` 1563 type M struct { 1564 One int 1565 Two int 1566 } 1567 type N struct { 1568 Zero int 1569 *M 1570 Three int 1571 } 1572 1573 if b, err := Marshal(N{Three: 3}); err != nil { 1574 t.Error(err) 1575 } else if string(b) != expectedString { 1576 t.Error( 1577 "got: ", string(b), 1578 "expected: ", expectedString, 1579 ) 1580 } 1581 1582 } 1583 1584 func TestGithubIssue44(t *testing.T) { 1585 var out rawJsonString 1586 if err := Unmarshal([]byte("null"), &out); err != nil { 1587 t.Fatal(err) 1588 } 1589 if out != "null" { 1590 t.Errorf("wanted \"null\" but got %q", out) 1591 } 1592 } 1593 1594 type issue107Foo struct { 1595 Bar *issue107Bar 1596 } 1597 1598 type issue107Bar struct { 1599 Foo *issue107Foo 1600 } 1601 1602 func TestGithubIssue107(t *testing.T) { 1603 f := &issue107Foo{} 1604 b := &issue107Bar{} 1605 f.Bar = b 1606 b.Foo = f 1607 1608 _, err := Marshal(f) // must not crash 1609 switch err.(type) { 1610 case *UnsupportedValueError: 1611 default: 1612 t.Errorf("marshaling a cycling data structure was expected to return an unsupported value error but got %T", err) 1613 } 1614 } 1615 1616 type rawJsonString string 1617 1618 func (r *rawJsonString) UnmarshalJSON(b []byte) error { 1619 if len(b) == 0 { 1620 *r = "null" 1621 } else { 1622 *r = rawJsonString(b) 1623 } 1624 return nil 1625 } 1626 1627 func TestSetTrustRawMessage(t *testing.T) { 1628 buf := &bytes.Buffer{} 1629 enc := NewEncoder(buf) 1630 enc.SetTrustRawMessage(true) 1631 1632 // "Good" values are encoded in the regular way 1633 m := map[string]json.RawMessage{ 1634 "k": json.RawMessage(`"value"`), 1635 } 1636 if err := enc.Encode(m); err != nil { 1637 t.Error(err) 1638 } 1639 1640 b := buf.Bytes() 1641 exp := []byte(`{"k":"value"}`) 1642 exp = append(exp, '\n') 1643 if bytes.Compare(exp, b) != 0 { 1644 t.Error( 1645 "unexpected encoding:", 1646 "expected", exp, 1647 "got", b, 1648 ) 1649 } 1650 1651 // "Bad" values are encoded without checking and throwing an error 1652 buf.Reset() 1653 m = map[string]json.RawMessage{ 1654 "k": json.RawMessage(`bad"value`), 1655 } 1656 if err := enc.Encode(m); err != nil { 1657 t.Error(err) 1658 } 1659 1660 b = buf.Bytes() 1661 exp = []byte(`{"k":bad"value}`) 1662 exp = append(exp, '\n') 1663 if bytes.Compare(exp, b) != 0 { 1664 t.Error( 1665 "unexpected encoding:", 1666 "expected", exp, 1667 "got", b, 1668 ) 1669 } 1670 } 1671 1672 func TestSetAppendNewline(t *testing.T) { 1673 buf := &bytes.Buffer{} 1674 enc := NewEncoder(buf) 1675 1676 m := "value" 1677 1678 // Default encoding adds an extra newline 1679 if err := enc.Encode(m); err != nil { 1680 t.Error(err) 1681 } 1682 b := buf.Bytes() 1683 exp := []byte(`"value"`) 1684 exp = append(exp, '\n') 1685 if bytes.Compare(exp, b) != 0 { 1686 t.Error( 1687 "unexpected encoding:", 1688 "expected", exp, 1689 "got", b, 1690 ) 1691 } 1692 1693 // With SetAppendNewline(false), there shouldn't be a newline in the output 1694 buf.Reset() 1695 enc.SetAppendNewline(false) 1696 if err := enc.Encode(m); err != nil { 1697 t.Error(err) 1698 } 1699 b = buf.Bytes() 1700 exp = []byte(`"value"`) 1701 if bytes.Compare(exp, b) != 0 { 1702 t.Error( 1703 "unexpected encoding:", 1704 "expected", exp, 1705 "got", b, 1706 ) 1707 } 1708 } 1709 1710 func TestEscapeString(t *testing.T) { 1711 b := Escape(`value`) 1712 x := []byte(`"value"`) 1713 1714 if !bytes.Equal(x, b) { 1715 t.Error( 1716 "unexpected encoding:", 1717 "expected", string(x), 1718 "got", string(b), 1719 ) 1720 } 1721 } 1722 1723 func TestAppendEscape(t *testing.T) { 1724 t.Run("basic", func(t *testing.T) { 1725 b := AppendEscape([]byte{}, `value`, AppendFlags(0)) 1726 exp := []byte(`"value"`) 1727 if bytes.Compare(exp, b) != 0 { 1728 t.Error( 1729 "unexpected encoding:", 1730 "expected", exp, 1731 "got", b, 1732 ) 1733 } 1734 }) 1735 1736 t.Run("escaped", func(t *testing.T) { 1737 b := AppendEscape([]byte{}, `"escaped" <value>`, EscapeHTML) 1738 exp := []byte(`"\"escaped\"\t\u003cvalue\u003e"`) 1739 if bytes.Compare(exp, b) != 0 { 1740 t.Error( 1741 "unexpected encoding:", 1742 "expected", exp, 1743 "got", b, 1744 ) 1745 } 1746 }) 1747 1748 t.Run("build", func(t *testing.T) { 1749 b := []byte{} 1750 b = append(b, '{') 1751 b = AppendEscape(b, `key`, EscapeHTML) 1752 b = append(b, ':') 1753 b = AppendEscape(b, `"escaped" <value>`, EscapeHTML) 1754 b = append(b, '}') 1755 exp := []byte(`{"key":"\"escaped\"\t\u003cvalue\u003e"}`) 1756 if bytes.Compare(exp, b) != 0 { 1757 t.Error( 1758 "unexpected encoding:", 1759 "expected", exp, 1760 "got", b, 1761 ) 1762 } 1763 }) 1764 } 1765 1766 func TestUnescapeString(t *testing.T) { 1767 b := Unescape([]byte(`"value"`)) 1768 x := []byte(`value`) 1769 1770 if !bytes.Equal(x, b) { 1771 t.Error( 1772 "unexpected decoding:", 1773 "expected", string(x), 1774 "got", string(b), 1775 ) 1776 } 1777 } 1778 1779 func TestAppendUnescape(t *testing.T) { 1780 t.Run("basic", func(t *testing.T) { 1781 out := AppendUnescape([]byte{}, []byte(`"value"`), ParseFlags(0)) 1782 exp := []byte("value") 1783 if bytes.Compare(exp, out) != 0 { 1784 t.Error( 1785 "unexpected decoding:", 1786 "expected", exp, 1787 "got", out, 1788 ) 1789 } 1790 }) 1791 1792 t.Run("escaped", func(t *testing.T) { 1793 b := AppendUnescape([]byte{}, []byte(`"\"escaped\"\t\u003cvalue\u003e"`), ParseFlags(0)) 1794 exp := []byte(`"escaped" <value>`) 1795 if bytes.Compare(exp, b) != 0 { 1796 t.Error( 1797 "unexpected encoding:", 1798 "expected", exp, 1799 "got", b, 1800 ) 1801 } 1802 }) 1803 1804 t.Run("build", func(t *testing.T) { 1805 b := []byte{} 1806 b = append(b, []byte(`{"key":`)...) 1807 b = AppendUnescape(b, []byte(`"\"escaped\"\t\u003cvalue\u003e"`), ParseFlags(0)) 1808 b = append(b, '}') 1809 exp := []byte(`{"key":"escaped" <value>}`) 1810 if bytes.Compare(exp, b) != 0 { 1811 t.Error( 1812 "unexpected encoding:", 1813 "expected", string(exp), 1814 "got", string(b), 1815 ) 1816 } 1817 }) 1818 } 1819 1820 func BenchmarkUnescape(b *testing.B) { 1821 s := []byte(`"\"escaped\"\t\u003cvalue\u003e"`) 1822 out := []byte{} 1823 for i := 0; i < b.N; i++ { 1824 out = Unescape(s) 1825 } 1826 1827 b.Log(string(out)) 1828 } 1829 1830 func BenchmarkUnmarshalField(b *testing.B) { 1831 s := []byte(`"\"escaped\"\t\u003cvalue\u003e"`) 1832 var v string 1833 1834 for i := 0; i < b.N; i++ { 1835 json.Unmarshal(s, &v) 1836 } 1837 1838 b.Log(v) 1839 } 1840 1841 func TestKind(t *testing.T) { 1842 for _, test := range []struct { 1843 kind Kind 1844 class Kind 1845 }{ 1846 {kind: 0, class: 0}, 1847 {kind: Null, class: Null}, 1848 {kind: False, class: Bool}, 1849 {kind: True, class: Bool}, 1850 {kind: Num, class: Num}, 1851 {kind: Uint, class: Num}, 1852 {kind: Int, class: Num}, 1853 {kind: Float, class: Num}, 1854 {kind: String, class: String}, 1855 {kind: Unescaped, class: String}, 1856 {kind: Array, class: Array}, 1857 {kind: Object, class: Object}, 1858 } { 1859 if class := test.kind.Class(); class != test.class { 1860 t.Errorf("class of kind(%d) mismatch: want=%d got=%d", test.kind, test.class, class) 1861 } 1862 } 1863 }