github.com/ActiveState/go@v0.0.0-20170614201249-0b81c023a722/src/encoding/json/encode_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package json 6 7 import ( 8 "bytes" 9 "fmt" 10 "log" 11 "math" 12 "reflect" 13 "regexp" 14 "strconv" 15 "testing" 16 "unicode" 17 ) 18 19 type Optionals struct { 20 Sr string `json:"sr"` 21 So string `json:"so,omitempty"` 22 Sw string `json:"-"` 23 24 Ir int `json:"omitempty"` // actually named omitempty, not an option 25 Io int `json:"io,omitempty"` 26 27 Slr []string `json:"slr,random"` 28 Slo []string `json:"slo,omitempty"` 29 30 Mr map[string]interface{} `json:"mr"` 31 Mo map[string]interface{} `json:",omitempty"` 32 33 Fr float64 `json:"fr"` 34 Fo float64 `json:"fo,omitempty"` 35 36 Br bool `json:"br"` 37 Bo bool `json:"bo,omitempty"` 38 39 Ur uint `json:"ur"` 40 Uo uint `json:"uo,omitempty"` 41 42 Str struct{} `json:"str"` 43 Sto struct{} `json:"sto,omitempty"` 44 } 45 46 var optionalsExpected = `{ 47 "sr": "", 48 "omitempty": 0, 49 "slr": null, 50 "mr": {}, 51 "fr": 0, 52 "br": false, 53 "ur": 0, 54 "str": {}, 55 "sto": {} 56 }` 57 58 func TestOmitEmpty(t *testing.T) { 59 var o Optionals 60 o.Sw = "something" 61 o.Mr = map[string]interface{}{} 62 o.Mo = map[string]interface{}{} 63 64 got, err := MarshalIndent(&o, "", " ") 65 if err != nil { 66 t.Fatal(err) 67 } 68 if got := string(got); got != optionalsExpected { 69 t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected) 70 } 71 } 72 73 type StringTag struct { 74 BoolStr bool `json:",string"` 75 IntStr int64 `json:",string"` 76 StrStr string `json:",string"` 77 } 78 79 var stringTagExpected = `{ 80 "BoolStr": "true", 81 "IntStr": "42", 82 "StrStr": "\"xzbit\"" 83 }` 84 85 func TestStringTag(t *testing.T) { 86 var s StringTag 87 s.BoolStr = true 88 s.IntStr = 42 89 s.StrStr = "xzbit" 90 got, err := MarshalIndent(&s, "", " ") 91 if err != nil { 92 t.Fatal(err) 93 } 94 if got := string(got); got != stringTagExpected { 95 t.Fatalf(" got: %s\nwant: %s\n", got, stringTagExpected) 96 } 97 98 // Verify that it round-trips. 99 var s2 StringTag 100 err = NewDecoder(bytes.NewReader(got)).Decode(&s2) 101 if err != nil { 102 t.Fatalf("Decode: %v", err) 103 } 104 if !reflect.DeepEqual(s, s2) { 105 t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2) 106 } 107 } 108 109 // byte slices are special even if they're renamed types. 110 type renamedByte byte 111 type renamedByteSlice []byte 112 type renamedRenamedByteSlice []renamedByte 113 114 func TestEncodeRenamedByteSlice(t *testing.T) { 115 s := renamedByteSlice("abc") 116 result, err := Marshal(s) 117 if err != nil { 118 t.Fatal(err) 119 } 120 expect := `"YWJj"` 121 if string(result) != expect { 122 t.Errorf(" got %s want %s", result, expect) 123 } 124 r := renamedRenamedByteSlice("abc") 125 result, err = Marshal(r) 126 if err != nil { 127 t.Fatal(err) 128 } 129 if string(result) != expect { 130 t.Errorf(" got %s want %s", result, expect) 131 } 132 } 133 134 var unsupportedValues = []interface{}{ 135 math.NaN(), 136 math.Inf(-1), 137 math.Inf(1), 138 } 139 140 func TestUnsupportedValues(t *testing.T) { 141 for _, v := range unsupportedValues { 142 if _, err := Marshal(v); err != nil { 143 if _, ok := err.(*UnsupportedValueError); !ok { 144 t.Errorf("for %v, got %T want UnsupportedValueError", v, err) 145 } 146 } else { 147 t.Errorf("for %v, expected error", v) 148 } 149 } 150 } 151 152 // Ref has Marshaler and Unmarshaler methods with pointer receiver. 153 type Ref int 154 155 func (*Ref) MarshalJSON() ([]byte, error) { 156 return []byte(`"ref"`), nil 157 } 158 159 func (r *Ref) UnmarshalJSON([]byte) error { 160 *r = 12 161 return nil 162 } 163 164 // Val has Marshaler methods with value receiver. 165 type Val int 166 167 func (Val) MarshalJSON() ([]byte, error) { 168 return []byte(`"val"`), nil 169 } 170 171 // RefText has Marshaler and Unmarshaler methods with pointer receiver. 172 type RefText int 173 174 func (*RefText) MarshalText() ([]byte, error) { 175 return []byte(`"ref"`), nil 176 } 177 178 func (r *RefText) UnmarshalText([]byte) error { 179 *r = 13 180 return nil 181 } 182 183 // ValText has Marshaler methods with value receiver. 184 type ValText int 185 186 func (ValText) MarshalText() ([]byte, error) { 187 return []byte(`"val"`), nil 188 } 189 190 func TestRefValMarshal(t *testing.T) { 191 var s = struct { 192 R0 Ref 193 R1 *Ref 194 R2 RefText 195 R3 *RefText 196 V0 Val 197 V1 *Val 198 V2 ValText 199 V3 *ValText 200 }{ 201 R0: 12, 202 R1: new(Ref), 203 R2: 14, 204 R3: new(RefText), 205 V0: 13, 206 V1: new(Val), 207 V2: 15, 208 V3: new(ValText), 209 } 210 const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}` 211 b, err := Marshal(&s) 212 if err != nil { 213 t.Fatalf("Marshal: %v", err) 214 } 215 if got := string(b); got != want { 216 t.Errorf("got %q, want %q", got, want) 217 } 218 } 219 220 // C implements Marshaler and returns unescaped JSON. 221 type C int 222 223 func (C) MarshalJSON() ([]byte, error) { 224 return []byte(`"<&>"`), nil 225 } 226 227 // CText implements Marshaler and returns unescaped text. 228 type CText int 229 230 func (CText) MarshalText() ([]byte, error) { 231 return []byte(`"<&>"`), nil 232 } 233 234 func TestMarshalerEscaping(t *testing.T) { 235 var c C 236 want := `"\u003c\u0026\u003e"` 237 b, err := Marshal(c) 238 if err != nil { 239 t.Fatalf("Marshal(c): %v", err) 240 } 241 if got := string(b); got != want { 242 t.Errorf("Marshal(c) = %#q, want %#q", got, want) 243 } 244 245 var ct CText 246 want = `"\"\u003c\u0026\u003e\""` 247 b, err = Marshal(ct) 248 if err != nil { 249 t.Fatalf("Marshal(ct): %v", err) 250 } 251 if got := string(b); got != want { 252 t.Errorf("Marshal(ct) = %#q, want %#q", got, want) 253 } 254 } 255 256 type IntType int 257 258 type MyStruct struct { 259 IntType 260 } 261 262 func TestAnonymousNonstruct(t *testing.T) { 263 var i IntType = 11 264 a := MyStruct{i} 265 const want = `{"IntType":11}` 266 267 b, err := Marshal(a) 268 if err != nil { 269 t.Fatalf("Marshal: %v", err) 270 } 271 if got := string(b); got != want { 272 t.Errorf("got %q, want %q", got, want) 273 } 274 } 275 276 type unexportedIntType int 277 278 type MyStructWithUnexportedIntType struct { 279 unexportedIntType 280 } 281 282 func TestAnonymousNonstructWithUnexportedType(t *testing.T) { 283 a := MyStructWithUnexportedIntType{11} 284 const want = `{}` 285 286 b, err := Marshal(a) 287 if err != nil { 288 t.Fatalf("Marshal: %v", err) 289 } 290 if got := string(b); got != want { 291 t.Errorf("got %q, want %q", got, want) 292 } 293 } 294 295 type MyStructContainingUnexportedStruct struct { 296 unexportedStructType1 297 unexportedIntType 298 } 299 300 type unexportedStructType1 struct { 301 ExportedIntType1 302 unexportedIntType 303 unexportedStructType2 304 } 305 306 type unexportedStructType2 struct { 307 ExportedIntType2 308 unexportedIntType 309 } 310 311 type ExportedIntType1 int 312 type ExportedIntType2 int 313 314 func TestUnexportedAnonymousStructWithExportedType(t *testing.T) { 315 s2 := unexportedStructType2{3, 4} 316 s1 := unexportedStructType1{1, 2, s2} 317 a := MyStructContainingUnexportedStruct{s1, 6} 318 const want = `{"ExportedIntType1":1,"ExportedIntType2":3}` 319 320 b, err := Marshal(a) 321 if err != nil { 322 t.Fatalf("Marshal: %v", err) 323 } 324 if got := string(b); got != want { 325 t.Errorf("got %q, want %q", got, want) 326 } 327 } 328 329 type BugA struct { 330 S string 331 } 332 333 type BugB struct { 334 BugA 335 S string 336 } 337 338 type BugC struct { 339 S string 340 } 341 342 // Legal Go: We never use the repeated embedded field (S). 343 type BugX struct { 344 A int 345 BugA 346 BugB 347 } 348 349 // Issue 16042. Even if a nil interface value is passed in 350 // as long as it implements MarshalJSON, it should be marshaled. 351 type nilMarshaler string 352 353 func (nm *nilMarshaler) MarshalJSON() ([]byte, error) { 354 if nm == nil { 355 return Marshal("0zenil0") 356 } 357 return Marshal("zenil:" + string(*nm)) 358 } 359 360 // Issue 16042. 361 func TestNilMarshal(t *testing.T) { 362 testCases := []struct { 363 v interface{} 364 want string 365 }{ 366 {v: nil, want: `null`}, 367 {v: new(float64), want: `0`}, 368 {v: []interface{}(nil), want: `null`}, 369 {v: []string(nil), want: `null`}, 370 {v: map[string]string(nil), want: `null`}, 371 {v: []byte(nil), want: `null`}, 372 {v: struct{ M string }{"gopher"}, want: `{"M":"gopher"}`}, 373 {v: struct{ M Marshaler }{}, want: `{"M":null}`}, 374 {v: struct{ M Marshaler }{(*nilMarshaler)(nil)}, want: `{"M":"0zenil0"}`}, 375 {v: struct{ M interface{} }{(*nilMarshaler)(nil)}, want: `{"M":null}`}, 376 } 377 378 for _, tt := range testCases { 379 out, err := Marshal(tt.v) 380 if err != nil || string(out) != tt.want { 381 t.Errorf("Marshal(%#v) = %#q, %#v, want %#q, nil", tt.v, out, err, tt.want) 382 continue 383 } 384 } 385 } 386 387 // Issue 5245. 388 func TestEmbeddedBug(t *testing.T) { 389 v := BugB{ 390 BugA{"A"}, 391 "B", 392 } 393 b, err := Marshal(v) 394 if err != nil { 395 t.Fatal("Marshal:", err) 396 } 397 want := `{"S":"B"}` 398 got := string(b) 399 if got != want { 400 t.Fatalf("Marshal: got %s want %s", got, want) 401 } 402 // Now check that the duplicate field, S, does not appear. 403 x := BugX{ 404 A: 23, 405 } 406 b, err = Marshal(x) 407 if err != nil { 408 t.Fatal("Marshal:", err) 409 } 410 want = `{"A":23}` 411 got = string(b) 412 if got != want { 413 t.Fatalf("Marshal: got %s want %s", got, want) 414 } 415 } 416 417 type BugD struct { // Same as BugA after tagging. 418 XXX string `json:"S"` 419 } 420 421 // BugD's tagged S field should dominate BugA's. 422 type BugY struct { 423 BugA 424 BugD 425 } 426 427 // Test that a field with a tag dominates untagged fields. 428 func TestTaggedFieldDominates(t *testing.T) { 429 v := BugY{ 430 BugA{"BugA"}, 431 BugD{"BugD"}, 432 } 433 b, err := Marshal(v) 434 if err != nil { 435 t.Fatal("Marshal:", err) 436 } 437 want := `{"S":"BugD"}` 438 got := string(b) 439 if got != want { 440 t.Fatalf("Marshal: got %s want %s", got, want) 441 } 442 } 443 444 // There are no tags here, so S should not appear. 445 type BugZ struct { 446 BugA 447 BugC 448 BugY // Contains a tagged S field through BugD; should not dominate. 449 } 450 451 func TestDuplicatedFieldDisappears(t *testing.T) { 452 v := BugZ{ 453 BugA{"BugA"}, 454 BugC{"BugC"}, 455 BugY{ 456 BugA{"nested BugA"}, 457 BugD{"nested BugD"}, 458 }, 459 } 460 b, err := Marshal(v) 461 if err != nil { 462 t.Fatal("Marshal:", err) 463 } 464 want := `{}` 465 got := string(b) 466 if got != want { 467 t.Fatalf("Marshal: got %s want %s", got, want) 468 } 469 } 470 471 func TestStringBytes(t *testing.T) { 472 t.Parallel() 473 // Test that encodeState.stringBytes and encodeState.string use the same encoding. 474 var r []rune 475 for i := '\u0000'; i <= unicode.MaxRune; i++ { 476 r = append(r, i) 477 } 478 s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too 479 480 for _, escapeHTML := range []bool{true, false} { 481 es := &encodeState{} 482 es.string(s, escapeHTML) 483 484 esBytes := &encodeState{} 485 esBytes.stringBytes([]byte(s), escapeHTML) 486 487 enc := es.Buffer.String() 488 encBytes := esBytes.Buffer.String() 489 if enc != encBytes { 490 i := 0 491 for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] { 492 i++ 493 } 494 enc = enc[i:] 495 encBytes = encBytes[i:] 496 i = 0 497 for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] { 498 i++ 499 } 500 enc = enc[:len(enc)-i] 501 encBytes = encBytes[:len(encBytes)-i] 502 503 if len(enc) > 20 { 504 enc = enc[:20] + "..." 505 } 506 if len(encBytes) > 20 { 507 encBytes = encBytes[:20] + "..." 508 } 509 510 t.Errorf("with escapeHTML=%t, encodings differ at %#q vs %#q", 511 escapeHTML, enc, encBytes) 512 } 513 } 514 } 515 516 func TestIssue10281(t *testing.T) { 517 type Foo struct { 518 N Number 519 } 520 x := Foo{Number(`invalid`)} 521 522 b, err := Marshal(&x) 523 if err == nil { 524 t.Errorf("Marshal(&x) = %#q; want error", b) 525 } 526 } 527 528 func TestHTMLEscape(t *testing.T) { 529 var b, want bytes.Buffer 530 m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}` 531 want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`)) 532 HTMLEscape(&b, []byte(m)) 533 if !bytes.Equal(b.Bytes(), want.Bytes()) { 534 t.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b.Bytes(), want.Bytes()) 535 } 536 } 537 538 // golang.org/issue/8582 539 func TestEncodePointerString(t *testing.T) { 540 type stringPointer struct { 541 N *int64 `json:"n,string"` 542 } 543 var n int64 = 42 544 b, err := Marshal(stringPointer{N: &n}) 545 if err != nil { 546 t.Fatalf("Marshal: %v", err) 547 } 548 if got, want := string(b), `{"n":"42"}`; got != want { 549 t.Errorf("Marshal = %s, want %s", got, want) 550 } 551 var back stringPointer 552 err = Unmarshal(b, &back) 553 if err != nil { 554 t.Fatalf("Unmarshal: %v", err) 555 } 556 if back.N == nil { 557 t.Fatalf("Unmarshaled nil N field") 558 } 559 if *back.N != 42 { 560 t.Fatalf("*N = %d; want 42", *back.N) 561 } 562 } 563 564 var encodeStringTests = []struct { 565 in string 566 out string 567 }{ 568 {"\x00", `"\u0000"`}, 569 {"\x01", `"\u0001"`}, 570 {"\x02", `"\u0002"`}, 571 {"\x03", `"\u0003"`}, 572 {"\x04", `"\u0004"`}, 573 {"\x05", `"\u0005"`}, 574 {"\x06", `"\u0006"`}, 575 {"\x07", `"\u0007"`}, 576 {"\x08", `"\u0008"`}, 577 {"\x09", `"\t"`}, 578 {"\x0a", `"\n"`}, 579 {"\x0b", `"\u000b"`}, 580 {"\x0c", `"\u000c"`}, 581 {"\x0d", `"\r"`}, 582 {"\x0e", `"\u000e"`}, 583 {"\x0f", `"\u000f"`}, 584 {"\x10", `"\u0010"`}, 585 {"\x11", `"\u0011"`}, 586 {"\x12", `"\u0012"`}, 587 {"\x13", `"\u0013"`}, 588 {"\x14", `"\u0014"`}, 589 {"\x15", `"\u0015"`}, 590 {"\x16", `"\u0016"`}, 591 {"\x17", `"\u0017"`}, 592 {"\x18", `"\u0018"`}, 593 {"\x19", `"\u0019"`}, 594 {"\x1a", `"\u001a"`}, 595 {"\x1b", `"\u001b"`}, 596 {"\x1c", `"\u001c"`}, 597 {"\x1d", `"\u001d"`}, 598 {"\x1e", `"\u001e"`}, 599 {"\x1f", `"\u001f"`}, 600 } 601 602 func TestEncodeString(t *testing.T) { 603 for _, tt := range encodeStringTests { 604 b, err := Marshal(tt.in) 605 if err != nil { 606 t.Errorf("Marshal(%q): %v", tt.in, err) 607 continue 608 } 609 out := string(b) 610 if out != tt.out { 611 t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out) 612 } 613 } 614 } 615 616 type jsonbyte byte 617 618 func (b jsonbyte) MarshalJSON() ([]byte, error) { return tenc(`{"JB":%d}`, b) } 619 620 type textbyte byte 621 622 func (b textbyte) MarshalText() ([]byte, error) { return tenc(`TB:%d`, b) } 623 624 type jsonint int 625 626 func (i jsonint) MarshalJSON() ([]byte, error) { return tenc(`{"JI":%d}`, i) } 627 628 type textint int 629 630 func (i textint) MarshalText() ([]byte, error) { return tenc(`TI:%d`, i) } 631 632 func tenc(format string, a ...interface{}) ([]byte, error) { 633 var buf bytes.Buffer 634 fmt.Fprintf(&buf, format, a...) 635 return buf.Bytes(), nil 636 } 637 638 // Issue 13783 639 func TestEncodeBytekind(t *testing.T) { 640 testdata := []struct { 641 data interface{} 642 want string 643 }{ 644 {byte(7), "7"}, 645 {jsonbyte(7), `{"JB":7}`}, 646 {textbyte(4), `"TB:4"`}, 647 {jsonint(5), `{"JI":5}`}, 648 {textint(1), `"TI:1"`}, 649 {[]byte{0, 1}, `"AAE="`}, 650 {[]jsonbyte{0, 1}, `[{"JB":0},{"JB":1}]`}, 651 {[][]jsonbyte{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`}, 652 {[]textbyte{2, 3}, `["TB:2","TB:3"]`}, 653 {[]jsonint{5, 4}, `[{"JI":5},{"JI":4}]`}, 654 {[]textint{9, 3}, `["TI:9","TI:3"]`}, 655 {[]int{9, 3}, `[9,3]`}, 656 } 657 for _, d := range testdata { 658 js, err := Marshal(d.data) 659 if err != nil { 660 t.Error(err) 661 continue 662 } 663 got, want := string(js), d.want 664 if got != want { 665 t.Errorf("got %s, want %s", got, want) 666 } 667 } 668 } 669 670 func TestTextMarshalerMapKeysAreSorted(t *testing.T) { 671 b, err := Marshal(map[unmarshalerText]int{ 672 {"x", "y"}: 1, 673 {"y", "x"}: 2, 674 {"a", "z"}: 3, 675 {"z", "a"}: 4, 676 }) 677 if err != nil { 678 t.Fatalf("Failed to Marshal text.Marshaler: %v", err) 679 } 680 const want = `{"a:z":3,"x:y":1,"y:x":2,"z:a":4}` 681 if string(b) != want { 682 t.Errorf("Marshal map with text.Marshaler keys: got %#q, want %#q", b, want) 683 } 684 } 685 686 var re = regexp.MustCompile 687 688 // syntactic checks on form of marshaled floating point numbers. 689 var badFloatREs = []*regexp.Regexp{ 690 re(`p`), // no binary exponential notation 691 re(`^\+`), // no leading + sign 692 re(`^-?0[^.]`), // no unnecessary leading zeros 693 re(`^-?\.`), // leading zero required before decimal point 694 re(`\.(e|$)`), // no trailing decimal 695 re(`\.[0-9]+0(e|$)`), // no trailing zero in fraction 696 re(`^-?(0|[0-9]{2,})\..*e`), // exponential notation must have normalized mantissa 697 re(`e[0-9]`), // positive exponent must be signed 698 re(`e[+-]0`), // exponent must not have leading zeros 699 re(`e-[1-6]$`), // not tiny enough for exponential notation 700 re(`e+(.|1.|20)$`), // not big enough for exponential notation 701 re(`^-?0\.0000000`), // too tiny, should use exponential notation 702 re(`^-?[0-9]{22}`), // too big, should use exponential notation 703 re(`[1-9][0-9]{16}[1-9]`), // too many significant digits in integer 704 re(`[1-9][0-9.]{17}[1-9]`), // too many significant digits in decimal 705 // below here for float32 only 706 re(`[1-9][0-9]{8}[1-9]`), // too many significant digits in integer 707 re(`[1-9][0-9.]{9}[1-9]`), // too many significant digits in decimal 708 } 709 710 func TestMarshalFloat(t *testing.T) { 711 t.Parallel() 712 nfail := 0 713 test := func(f float64, bits int) { 714 vf := interface{}(f) 715 if bits == 32 { 716 f = float64(float32(f)) // round 717 vf = float32(f) 718 } 719 bout, err := Marshal(vf) 720 if err != nil { 721 t.Errorf("Marshal(%T(%g)): %v", vf, vf, err) 722 nfail++ 723 return 724 } 725 out := string(bout) 726 727 // result must convert back to the same float 728 g, err := strconv.ParseFloat(out, bits) 729 if err != nil { 730 t.Errorf("Marshal(%T(%g)) = %q, cannot parse back: %v", vf, vf, out, err) 731 nfail++ 732 return 733 } 734 if f != g || fmt.Sprint(f) != fmt.Sprint(g) { // fmt.Sprint handles ±0 735 t.Errorf("Marshal(%T(%g)) = %q (is %g, not %g)", vf, vf, out, float32(g), vf) 736 nfail++ 737 return 738 } 739 740 bad := badFloatREs 741 if bits == 64 { 742 bad = bad[:len(bad)-2] 743 } 744 for _, re := range bad { 745 if re.MatchString(out) { 746 t.Errorf("Marshal(%T(%g)) = %q, must not match /%s/", vf, vf, out, re) 747 nfail++ 748 return 749 } 750 } 751 } 752 753 var ( 754 bigger = math.Inf(+1) 755 smaller = math.Inf(-1) 756 ) 757 758 var digits = "1.2345678901234567890123" 759 for i := len(digits); i >= 2; i-- { 760 for exp := -30; exp <= 30; exp++ { 761 for _, sign := range "+-" { 762 for bits := 32; bits <= 64; bits += 32 { 763 s := fmt.Sprintf("%c%se%d", sign, digits[:i], exp) 764 f, err := strconv.ParseFloat(s, bits) 765 if err != nil { 766 log.Fatal(err) 767 } 768 next := math.Nextafter 769 if bits == 32 { 770 next = func(g, h float64) float64 { 771 return float64(math.Nextafter32(float32(g), float32(h))) 772 } 773 } 774 test(f, bits) 775 test(next(f, bigger), bits) 776 test(next(f, smaller), bits) 777 if nfail > 50 { 778 t.Fatalf("stopping test early") 779 } 780 } 781 } 782 } 783 } 784 test(0, 64) 785 test(math.Copysign(0, -1), 64) 786 test(0, 32) 787 test(math.Copysign(0, -1), 32) 788 } 789 790 func TestMarshalRawMessageValue(t *testing.T) { 791 type ( 792 T1 struct { 793 M RawMessage `json:",omitempty"` 794 } 795 T2 struct { 796 M *RawMessage `json:",omitempty"` 797 } 798 ) 799 800 var ( 801 rawNil = RawMessage(nil) 802 rawEmpty = RawMessage([]byte{}) 803 rawText = RawMessage([]byte(`"foo"`)) 804 ) 805 806 tests := []struct { 807 in interface{} 808 want string 809 ok bool 810 }{ 811 // Test with nil RawMessage. 812 {rawNil, "null", true}, 813 {&rawNil, "null", true}, 814 {[]interface{}{rawNil}, "[null]", true}, 815 {&[]interface{}{rawNil}, "[null]", true}, 816 {[]interface{}{&rawNil}, "[null]", true}, 817 {&[]interface{}{&rawNil}, "[null]", true}, 818 {struct{ M RawMessage }{rawNil}, `{"M":null}`, true}, 819 {&struct{ M RawMessage }{rawNil}, `{"M":null}`, true}, 820 {struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true}, 821 {&struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true}, 822 {map[string]interface{}{"M": rawNil}, `{"M":null}`, true}, 823 {&map[string]interface{}{"M": rawNil}, `{"M":null}`, true}, 824 {map[string]interface{}{"M": &rawNil}, `{"M":null}`, true}, 825 {&map[string]interface{}{"M": &rawNil}, `{"M":null}`, true}, 826 {T1{rawNil}, "{}", true}, 827 {T2{&rawNil}, `{"M":null}`, true}, 828 {&T1{rawNil}, "{}", true}, 829 {&T2{&rawNil}, `{"M":null}`, true}, 830 831 // Test with empty, but non-nil, RawMessage. 832 {rawEmpty, "", false}, 833 {&rawEmpty, "", false}, 834 {[]interface{}{rawEmpty}, "", false}, 835 {&[]interface{}{rawEmpty}, "", false}, 836 {[]interface{}{&rawEmpty}, "", false}, 837 {&[]interface{}{&rawEmpty}, "", false}, 838 {struct{ X RawMessage }{rawEmpty}, "", false}, 839 {&struct{ X RawMessage }{rawEmpty}, "", false}, 840 {struct{ X *RawMessage }{&rawEmpty}, "", false}, 841 {&struct{ X *RawMessage }{&rawEmpty}, "", false}, 842 {map[string]interface{}{"nil": rawEmpty}, "", false}, 843 {&map[string]interface{}{"nil": rawEmpty}, "", false}, 844 {map[string]interface{}{"nil": &rawEmpty}, "", false}, 845 {&map[string]interface{}{"nil": &rawEmpty}, "", false}, 846 {T1{rawEmpty}, "{}", true}, 847 {T2{&rawEmpty}, "", false}, 848 {&T1{rawEmpty}, "{}", true}, 849 {&T2{&rawEmpty}, "", false}, 850 851 // Test with RawMessage with some text. 852 // 853 // The tests below marked with Issue6458 used to generate "ImZvbyI=" instead "foo". 854 // This behavior was intentionally changed in Go 1.8. 855 // See https://github.com/golang/go/issues/14493#issuecomment-255857318 856 {rawText, `"foo"`, true}, // Issue6458 857 {&rawText, `"foo"`, true}, 858 {[]interface{}{rawText}, `["foo"]`, true}, // Issue6458 859 {&[]interface{}{rawText}, `["foo"]`, true}, // Issue6458 860 {[]interface{}{&rawText}, `["foo"]`, true}, 861 {&[]interface{}{&rawText}, `["foo"]`, true}, 862 {struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true}, // Issue6458 863 {&struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true}, 864 {struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true}, 865 {&struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true}, 866 {map[string]interface{}{"M": rawText}, `{"M":"foo"}`, true}, // Issue6458 867 {&map[string]interface{}{"M": rawText}, `{"M":"foo"}`, true}, // Issue6458 868 {map[string]interface{}{"M": &rawText}, `{"M":"foo"}`, true}, 869 {&map[string]interface{}{"M": &rawText}, `{"M":"foo"}`, true}, 870 {T1{rawText}, `{"M":"foo"}`, true}, // Issue6458 871 {T2{&rawText}, `{"M":"foo"}`, true}, 872 {&T1{rawText}, `{"M":"foo"}`, true}, 873 {&T2{&rawText}, `{"M":"foo"}`, true}, 874 } 875 876 for i, tt := range tests { 877 b, err := Marshal(tt.in) 878 if ok := (err == nil); ok != tt.ok { 879 if err != nil { 880 t.Errorf("test %d, unexpected failure: %v", i, err) 881 } else { 882 t.Errorf("test %d, unexpected success", i) 883 } 884 } 885 if got := string(b); got != tt.want { 886 t.Errorf("test %d, Marshal(%#v) = %q, want %q", i, tt.in, got, tt.want) 887 } 888 } 889 }