github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/encoding/json/decode_test.go (about) 1 // Copyright 2010 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 "image" 11 "reflect" 12 "strings" 13 "testing" 14 "time" 15 ) 16 17 type T struct { 18 X string 19 Y int 20 Z int `json:"-"` 21 } 22 23 type U struct { 24 Alphabet string `json:"alpha"` 25 } 26 27 type V struct { 28 F1 interface{} 29 F2 int32 30 F3 Number 31 } 32 33 // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and 34 // without UseNumber 35 var ifaceNumAsFloat64 = map[string]interface{}{ 36 "k1": float64(1), 37 "k2": "s", 38 "k3": []interface{}{float64(1), float64(2.0), float64(3e-3)}, 39 "k4": map[string]interface{}{"kk1": "s", "kk2": float64(2)}, 40 } 41 42 var ifaceNumAsNumber = map[string]interface{}{ 43 "k1": Number("1"), 44 "k2": "s", 45 "k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")}, 46 "k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")}, 47 } 48 49 type tx struct { 50 x int 51 } 52 53 var txType = reflect.TypeOf((*tx)(nil)).Elem() 54 55 // A type that can unmarshal itself. 56 57 type unmarshaler struct { 58 T bool 59 } 60 61 func (u *unmarshaler) UnmarshalJSON(b []byte) error { 62 *u = unmarshaler{true} // All we need to see that UnmarshalJson is called. 63 return nil 64 } 65 66 type ustruct struct { 67 M unmarshaler 68 } 69 70 var ( 71 um0, um1 unmarshaler // target2 of unmarshaling 72 ump = &um1 73 umtrue = unmarshaler{true} 74 umslice = []unmarshaler{{true}} 75 umslicep = new([]unmarshaler) 76 umstruct = ustruct{unmarshaler{true}} 77 ) 78 79 // Test data structures for anonymous fields. 80 81 type Point struct { 82 Z int 83 } 84 85 type Top struct { 86 Level0 int 87 Embed0 88 *Embed0a 89 *Embed0b `json:"e,omitempty"` // treated as named 90 Embed0c `json:"-"` // ignored 91 Loop 92 Embed0p // has Point with X, Y, used 93 Embed0q // has Point with Z, used 94 } 95 96 type Embed0 struct { 97 Level1a int // overridden by Embed0a's Level1a with json tag 98 Level1b int // used because Embed0a's Level1b is renamed 99 Level1c int // used because Embed0a's Level1c is ignored 100 Level1d int // annihilated by Embed0a's Level1d 101 Level1e int `json:"x"` // annihilated by Embed0a.Level1e 102 } 103 104 type Embed0a struct { 105 Level1a int `json:"Level1a,omitempty"` 106 Level1b int `json:"LEVEL1B,omitempty"` 107 Level1c int `json:"-"` 108 Level1d int // annihilated by Embed0's Level1d 109 Level1f int `json:"x"` // annihilated by Embed0's Level1e 110 } 111 112 type Embed0b Embed0 113 114 type Embed0c Embed0 115 116 type Embed0p struct { 117 image.Point 118 } 119 120 type Embed0q struct { 121 Point 122 } 123 124 type Loop struct { 125 Loop1 int `json:",omitempty"` 126 Loop2 int `json:",omitempty"` 127 *Loop 128 } 129 130 // From reflect test: 131 // The X in S6 and S7 annihilate, but they also block the X in S8.S9. 132 type S5 struct { 133 S6 134 S7 135 S8 136 } 137 138 type S6 struct { 139 X int 140 } 141 142 type S7 S6 143 144 type S8 struct { 145 S9 146 } 147 148 type S9 struct { 149 X int 150 Y int 151 } 152 153 // From reflect test: 154 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9. 155 type S10 struct { 156 S11 157 S12 158 S13 159 } 160 161 type S11 struct { 162 S6 163 } 164 165 type S12 struct { 166 S6 167 } 168 169 type S13 struct { 170 S8 171 } 172 173 type unmarshalTest struct { 174 in string 175 ptr interface{} 176 out interface{} 177 err error 178 useNumber bool 179 } 180 181 type Ambig struct { 182 // Given "hello", the first match should win. 183 First int `json:"HELLO"` 184 Second int `json:"Hello"` 185 } 186 187 var unmarshalTests = []unmarshalTest{ 188 // basic types 189 {in: `true`, ptr: new(bool), out: true}, 190 {in: `1`, ptr: new(int), out: 1}, 191 {in: `1.2`, ptr: new(float64), out: 1.2}, 192 {in: `-5`, ptr: new(int16), out: int16(-5)}, 193 {in: `2`, ptr: new(Number), out: Number("2"), useNumber: true}, 194 {in: `2`, ptr: new(Number), out: Number("2")}, 195 {in: `2`, ptr: new(interface{}), out: float64(2.0)}, 196 {in: `2`, ptr: new(interface{}), out: Number("2"), useNumber: true}, 197 {in: `"a\u1234"`, ptr: new(string), out: "a\u1234"}, 198 {in: `"http:\/\/"`, ptr: new(string), out: "http://"}, 199 {in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"}, 200 {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, 201 {in: "null", ptr: new(interface{}), out: nil}, 202 {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf("")}}, 203 {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, 204 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}}, 205 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true}, 206 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsFloat64}, 207 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsNumber, useNumber: true}, 208 209 // raw values with whitespace 210 {in: "\n true ", ptr: new(bool), out: true}, 211 {in: "\t 1 ", ptr: new(int), out: 1}, 212 {in: "\r 1.2 ", ptr: new(float64), out: 1.2}, 213 {in: "\t -5 \n", ptr: new(int16), out: int16(-5)}, 214 {in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"}, 215 216 // Z has a "-" tag. 217 {in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}}, 218 219 {in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 220 {in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}}, 221 {in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}}, 222 223 // syntax errors 224 {in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}}, 225 {in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}}, 226 {in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true}, 227 228 // raw value errors 229 {in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 230 {in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}}, 231 {in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 232 {in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}}, 233 {in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 234 {in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}}, 235 {in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, 236 {in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}}, 237 238 // array tests 239 {in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}}, 240 {in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}}, 241 {in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}}, 242 243 // empty array to interface test 244 {in: `[]`, ptr: new([]interface{}), out: []interface{}{}}, 245 {in: `null`, ptr: new([]interface{}), out: []interface{}(nil)}, 246 {in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}}, 247 {in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}}, 248 249 // composite tests 250 {in: allValueIndent, ptr: new(All), out: allValue}, 251 {in: allValueCompact, ptr: new(All), out: allValue}, 252 {in: allValueIndent, ptr: new(*All), out: &allValue}, 253 {in: allValueCompact, ptr: new(*All), out: &allValue}, 254 {in: pallValueIndent, ptr: new(All), out: pallValue}, 255 {in: pallValueCompact, ptr: new(All), out: pallValue}, 256 {in: pallValueIndent, ptr: new(*All), out: &pallValue}, 257 {in: pallValueCompact, ptr: new(*All), out: &pallValue}, 258 259 // unmarshal interface test 260 {in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called 261 {in: `{"T":false}`, ptr: &ump, out: &umtrue}, 262 {in: `[{"T":false}]`, ptr: &umslice, out: umslice}, 263 {in: `[{"T":false}]`, ptr: &umslicep, out: &umslice}, 264 {in: `{"M":{"T":false}}`, ptr: &umstruct, out: umstruct}, 265 266 { 267 in: `{ 268 "Level0": 1, 269 "Level1b": 2, 270 "Level1c": 3, 271 "x": 4, 272 "Level1a": 5, 273 "LEVEL1B": 6, 274 "e": { 275 "Level1a": 8, 276 "Level1b": 9, 277 "Level1c": 10, 278 "Level1d": 11, 279 "x": 12 280 }, 281 "Loop1": 13, 282 "Loop2": 14, 283 "X": 15, 284 "Y": 16, 285 "Z": 17 286 }`, 287 ptr: new(Top), 288 out: Top{ 289 Level0: 1, 290 Embed0: Embed0{ 291 Level1b: 2, 292 Level1c: 3, 293 }, 294 Embed0a: &Embed0a{ 295 Level1a: 5, 296 Level1b: 6, 297 }, 298 Embed0b: &Embed0b{ 299 Level1a: 8, 300 Level1b: 9, 301 Level1c: 10, 302 Level1d: 11, 303 Level1e: 12, 304 }, 305 Loop: Loop{ 306 Loop1: 13, 307 Loop2: 14, 308 }, 309 Embed0p: Embed0p{ 310 Point: image.Point{X: 15, Y: 16}, 311 }, 312 Embed0q: Embed0q{ 313 Point: Point{Z: 17}, 314 }, 315 }, 316 }, 317 { 318 in: `{"hello": 1}`, 319 ptr: new(Ambig), 320 out: Ambig{First: 1}, 321 }, 322 323 { 324 in: `{"X": 1,"Y":2}`, 325 ptr: new(S5), 326 out: S5{S8: S8{S9: S9{Y: 2}}}, 327 }, 328 { 329 in: `{"X": 1,"Y":2}`, 330 ptr: new(S10), 331 out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}}, 332 }, 333 334 // invalid UTF-8 is coerced to valid UTF-8. 335 { 336 in: "\"hello\xffworld\"", 337 ptr: new(string), 338 out: "hello\ufffdworld", 339 }, 340 { 341 in: "\"hello\xc2\xc2world\"", 342 ptr: new(string), 343 out: "hello\ufffd\ufffdworld", 344 }, 345 { 346 in: "\"hello\xc2\xffworld\"", 347 ptr: new(string), 348 out: "hello\ufffd\ufffdworld", 349 }, 350 { 351 in: "\"hello\\ud800world\"", 352 ptr: new(string), 353 out: "hello\ufffdworld", 354 }, 355 { 356 in: "\"hello\\ud800\\ud800world\"", 357 ptr: new(string), 358 out: "hello\ufffd\ufffdworld", 359 }, 360 { 361 in: "\"hello\\ud800\\ud800world\"", 362 ptr: new(string), 363 out: "hello\ufffd\ufffdworld", 364 }, 365 { 366 in: "\"hello\xed\xa0\x80\xed\xb0\x80world\"", 367 ptr: new(string), 368 out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld", 369 }, 370 } 371 372 func TestMarshal(t *testing.T) { 373 b, err := Marshal(allValue) 374 if err != nil { 375 t.Fatalf("Marshal allValue: %v", err) 376 } 377 if string(b) != allValueCompact { 378 t.Errorf("Marshal allValueCompact") 379 diff(t, b, []byte(allValueCompact)) 380 return 381 } 382 383 b, err = Marshal(pallValue) 384 if err != nil { 385 t.Fatalf("Marshal pallValue: %v", err) 386 } 387 if string(b) != pallValueCompact { 388 t.Errorf("Marshal pallValueCompact") 389 diff(t, b, []byte(pallValueCompact)) 390 return 391 } 392 } 393 394 func TestMarshalBadUTF8(t *testing.T) { 395 s := "hello\xffworld" 396 b, err := Marshal(s) 397 if err == nil { 398 t.Fatal("Marshal bad UTF8: no error") 399 } 400 if len(b) != 0 { 401 t.Fatal("Marshal returned data") 402 } 403 if _, ok := err.(*InvalidUTF8Error); !ok { 404 t.Fatalf("Marshal did not return InvalidUTF8Error: %T %v", err, err) 405 } 406 } 407 408 func TestMarshalNumberZeroVal(t *testing.T) { 409 var n Number 410 out, err := Marshal(n) 411 if err != nil { 412 t.Fatal(err) 413 } 414 outStr := string(out) 415 if outStr != "0" { 416 t.Fatalf("Invalid zero val for Number: %q", outStr) 417 } 418 } 419 420 func TestUnmarshal(t *testing.T) { 421 for i, tt := range unmarshalTests { 422 var scan scanner 423 in := []byte(tt.in) 424 if err := checkValid(in, &scan); err != nil { 425 if !reflect.DeepEqual(err, tt.err) { 426 t.Errorf("#%d: checkValid: %#v", i, err) 427 continue 428 } 429 } 430 if tt.ptr == nil { 431 continue 432 } 433 // v = new(right-type) 434 v := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 435 dec := NewDecoder(bytes.NewBuffer(in)) 436 if tt.useNumber { 437 dec.UseNumber() 438 } 439 if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) { 440 t.Errorf("#%d: %v want %v", i, err, tt.err) 441 continue 442 } 443 if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { 444 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) 445 data, _ := Marshal(v.Elem().Interface()) 446 println(string(data)) 447 data, _ = Marshal(tt.out) 448 println(string(data)) 449 continue 450 } 451 452 // Check round trip. 453 if tt.err == nil { 454 enc, err := Marshal(v.Interface()) 455 if err != nil { 456 t.Errorf("#%d: error re-marshaling: %v", i, err) 457 continue 458 } 459 vv := reflect.New(reflect.TypeOf(tt.ptr).Elem()) 460 dec = NewDecoder(bytes.NewBuffer(enc)) 461 if tt.useNumber { 462 dec.UseNumber() 463 } 464 if err := dec.Decode(vv.Interface()); err != nil { 465 t.Errorf("#%d: error re-unmarshaling: %v", i, err) 466 continue 467 } 468 if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) { 469 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface()) 470 continue 471 } 472 } 473 } 474 } 475 476 func TestUnmarshalMarshal(t *testing.T) { 477 initBig() 478 var v interface{} 479 if err := Unmarshal(jsonBig, &v); err != nil { 480 t.Fatalf("Unmarshal: %v", err) 481 } 482 b, err := Marshal(v) 483 if err != nil { 484 t.Fatalf("Marshal: %v", err) 485 } 486 if !bytes.Equal(jsonBig, b) { 487 t.Errorf("Marshal jsonBig") 488 diff(t, b, jsonBig) 489 return 490 } 491 } 492 493 var numberTests = []struct { 494 in string 495 i int64 496 intErr string 497 f float64 498 floatErr string 499 }{ 500 {in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1}, 501 {in: "-12", i: -12, f: -12.0}, 502 {in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"}, 503 } 504 505 // Independent of Decode, basic coverage of the accessors in Number 506 func TestNumberAccessors(t *testing.T) { 507 for _, tt := range numberTests { 508 n := Number(tt.in) 509 if s := n.String(); s != tt.in { 510 t.Errorf("Number(%q).String() is %q", tt.in, s) 511 } 512 if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i { 513 t.Errorf("Number(%q).Int64() is %d", tt.in, i) 514 } else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) { 515 t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err) 516 } 517 if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f { 518 t.Errorf("Number(%q).Float64() is %g", tt.in, f) 519 } else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) { 520 t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err) 521 } 522 } 523 } 524 525 func TestLargeByteSlice(t *testing.T) { 526 s0 := make([]byte, 2000) 527 for i := range s0 { 528 s0[i] = byte(i) 529 } 530 b, err := Marshal(s0) 531 if err != nil { 532 t.Fatalf("Marshal: %v", err) 533 } 534 var s1 []byte 535 if err := Unmarshal(b, &s1); err != nil { 536 t.Fatalf("Unmarshal: %v", err) 537 } 538 if !bytes.Equal(s0, s1) { 539 t.Errorf("Marshal large byte slice") 540 diff(t, s0, s1) 541 } 542 } 543 544 type Xint struct { 545 X int 546 } 547 548 func TestUnmarshalInterface(t *testing.T) { 549 var xint Xint 550 var i interface{} = &xint 551 if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil { 552 t.Fatalf("Unmarshal: %v", err) 553 } 554 if xint.X != 1 { 555 t.Fatalf("Did not write to xint") 556 } 557 } 558 559 func TestUnmarshalPtrPtr(t *testing.T) { 560 var xint Xint 561 pxint := &xint 562 if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil { 563 t.Fatalf("Unmarshal: %v", err) 564 } 565 if xint.X != 1 { 566 t.Fatalf("Did not write to xint") 567 } 568 } 569 570 func TestEscape(t *testing.T) { 571 const input = `"foobar"<html>` 572 const expected = `"\"foobar\"\u003chtml\u003e"` 573 b, err := Marshal(input) 574 if err != nil { 575 t.Fatalf("Marshal error: %v", err) 576 } 577 if s := string(b); s != expected { 578 t.Errorf("Encoding of [%s] was [%s], want [%s]", input, s, expected) 579 } 580 } 581 582 // WrongString is a struct that's misusing the ,string modifier. 583 type WrongString struct { 584 Message string `json:"result,string"` 585 } 586 587 type wrongStringTest struct { 588 in, err string 589 } 590 591 var wrongStringTests = []wrongStringTest{ 592 {`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`}, 593 {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`}, 594 {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`}, 595 } 596 597 // If people misuse the ,string modifier, the error message should be 598 // helpful, telling the user that they're doing it wrong. 599 func TestErrorMessageFromMisusedString(t *testing.T) { 600 for n, tt := range wrongStringTests { 601 r := strings.NewReader(tt.in) 602 var s WrongString 603 err := NewDecoder(r).Decode(&s) 604 got := fmt.Sprintf("%v", err) 605 if got != tt.err { 606 t.Errorf("%d. got err = %q, want %q", n, got, tt.err) 607 } 608 } 609 } 610 611 func noSpace(c rune) rune { 612 if isSpace(c) { 613 return -1 614 } 615 return c 616 } 617 618 type All struct { 619 Bool bool 620 Int int 621 Int8 int8 622 Int16 int16 623 Int32 int32 624 Int64 int64 625 Uint uint 626 Uint8 uint8 627 Uint16 uint16 628 Uint32 uint32 629 Uint64 uint64 630 Uintptr uintptr 631 Float32 float32 632 Float64 float64 633 634 Foo string `json:"bar"` 635 Foo2 string `json:"bar2,dummyopt"` 636 637 IntStr int64 `json:",string"` 638 639 PBool *bool 640 PInt *int 641 PInt8 *int8 642 PInt16 *int16 643 PInt32 *int32 644 PInt64 *int64 645 PUint *uint 646 PUint8 *uint8 647 PUint16 *uint16 648 PUint32 *uint32 649 PUint64 *uint64 650 PUintptr *uintptr 651 PFloat32 *float32 652 PFloat64 *float64 653 654 String string 655 PString *string 656 657 Map map[string]Small 658 MapP map[string]*Small 659 PMap *map[string]Small 660 PMapP *map[string]*Small 661 662 EmptyMap map[string]Small 663 NilMap map[string]Small 664 665 Slice []Small 666 SliceP []*Small 667 PSlice *[]Small 668 PSliceP *[]*Small 669 670 EmptySlice []Small 671 NilSlice []Small 672 673 StringSlice []string 674 ByteSlice []byte 675 676 Small Small 677 PSmall *Small 678 PPSmall **Small 679 680 Interface interface{} 681 PInterface *interface{} 682 683 unexported int 684 } 685 686 type Small struct { 687 Tag string 688 } 689 690 var allValue = All{ 691 Bool: true, 692 Int: 2, 693 Int8: 3, 694 Int16: 4, 695 Int32: 5, 696 Int64: 6, 697 Uint: 7, 698 Uint8: 8, 699 Uint16: 9, 700 Uint32: 10, 701 Uint64: 11, 702 Uintptr: 12, 703 Float32: 14.1, 704 Float64: 15.1, 705 Foo: "foo", 706 Foo2: "foo2", 707 IntStr: 42, 708 String: "16", 709 Map: map[string]Small{ 710 "17": {Tag: "tag17"}, 711 "18": {Tag: "tag18"}, 712 }, 713 MapP: map[string]*Small{ 714 "19": {Tag: "tag19"}, 715 "20": nil, 716 }, 717 EmptyMap: map[string]Small{}, 718 Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}}, 719 SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}}, 720 EmptySlice: []Small{}, 721 StringSlice: []string{"str24", "str25", "str26"}, 722 ByteSlice: []byte{27, 28, 29}, 723 Small: Small{Tag: "tag30"}, 724 PSmall: &Small{Tag: "tag31"}, 725 Interface: 5.2, 726 } 727 728 var pallValue = All{ 729 PBool: &allValue.Bool, 730 PInt: &allValue.Int, 731 PInt8: &allValue.Int8, 732 PInt16: &allValue.Int16, 733 PInt32: &allValue.Int32, 734 PInt64: &allValue.Int64, 735 PUint: &allValue.Uint, 736 PUint8: &allValue.Uint8, 737 PUint16: &allValue.Uint16, 738 PUint32: &allValue.Uint32, 739 PUint64: &allValue.Uint64, 740 PUintptr: &allValue.Uintptr, 741 PFloat32: &allValue.Float32, 742 PFloat64: &allValue.Float64, 743 PString: &allValue.String, 744 PMap: &allValue.Map, 745 PMapP: &allValue.MapP, 746 PSlice: &allValue.Slice, 747 PSliceP: &allValue.SliceP, 748 PPSmall: &allValue.PSmall, 749 PInterface: &allValue.Interface, 750 } 751 752 var allValueIndent = `{ 753 "Bool": true, 754 "Int": 2, 755 "Int8": 3, 756 "Int16": 4, 757 "Int32": 5, 758 "Int64": 6, 759 "Uint": 7, 760 "Uint8": 8, 761 "Uint16": 9, 762 "Uint32": 10, 763 "Uint64": 11, 764 "Uintptr": 12, 765 "Float32": 14.1, 766 "Float64": 15.1, 767 "bar": "foo", 768 "bar2": "foo2", 769 "IntStr": "42", 770 "PBool": null, 771 "PInt": null, 772 "PInt8": null, 773 "PInt16": null, 774 "PInt32": null, 775 "PInt64": null, 776 "PUint": null, 777 "PUint8": null, 778 "PUint16": null, 779 "PUint32": null, 780 "PUint64": null, 781 "PUintptr": null, 782 "PFloat32": null, 783 "PFloat64": null, 784 "String": "16", 785 "PString": null, 786 "Map": { 787 "17": { 788 "Tag": "tag17" 789 }, 790 "18": { 791 "Tag": "tag18" 792 } 793 }, 794 "MapP": { 795 "19": { 796 "Tag": "tag19" 797 }, 798 "20": null 799 }, 800 "PMap": null, 801 "PMapP": null, 802 "EmptyMap": {}, 803 "NilMap": null, 804 "Slice": [ 805 { 806 "Tag": "tag20" 807 }, 808 { 809 "Tag": "tag21" 810 } 811 ], 812 "SliceP": [ 813 { 814 "Tag": "tag22" 815 }, 816 null, 817 { 818 "Tag": "tag23" 819 } 820 ], 821 "PSlice": null, 822 "PSliceP": null, 823 "EmptySlice": [], 824 "NilSlice": null, 825 "StringSlice": [ 826 "str24", 827 "str25", 828 "str26" 829 ], 830 "ByteSlice": "Gxwd", 831 "Small": { 832 "Tag": "tag30" 833 }, 834 "PSmall": { 835 "Tag": "tag31" 836 }, 837 "PPSmall": null, 838 "Interface": 5.2, 839 "PInterface": null 840 }` 841 842 var allValueCompact = strings.Map(noSpace, allValueIndent) 843 844 var pallValueIndent = `{ 845 "Bool": false, 846 "Int": 0, 847 "Int8": 0, 848 "Int16": 0, 849 "Int32": 0, 850 "Int64": 0, 851 "Uint": 0, 852 "Uint8": 0, 853 "Uint16": 0, 854 "Uint32": 0, 855 "Uint64": 0, 856 "Uintptr": 0, 857 "Float32": 0, 858 "Float64": 0, 859 "bar": "", 860 "bar2": "", 861 "IntStr": "0", 862 "PBool": true, 863 "PInt": 2, 864 "PInt8": 3, 865 "PInt16": 4, 866 "PInt32": 5, 867 "PInt64": 6, 868 "PUint": 7, 869 "PUint8": 8, 870 "PUint16": 9, 871 "PUint32": 10, 872 "PUint64": 11, 873 "PUintptr": 12, 874 "PFloat32": 14.1, 875 "PFloat64": 15.1, 876 "String": "", 877 "PString": "16", 878 "Map": null, 879 "MapP": null, 880 "PMap": { 881 "17": { 882 "Tag": "tag17" 883 }, 884 "18": { 885 "Tag": "tag18" 886 } 887 }, 888 "PMapP": { 889 "19": { 890 "Tag": "tag19" 891 }, 892 "20": null 893 }, 894 "EmptyMap": null, 895 "NilMap": null, 896 "Slice": null, 897 "SliceP": null, 898 "PSlice": [ 899 { 900 "Tag": "tag20" 901 }, 902 { 903 "Tag": "tag21" 904 } 905 ], 906 "PSliceP": [ 907 { 908 "Tag": "tag22" 909 }, 910 null, 911 { 912 "Tag": "tag23" 913 } 914 ], 915 "EmptySlice": null, 916 "NilSlice": null, 917 "StringSlice": null, 918 "ByteSlice": null, 919 "Small": { 920 "Tag": "" 921 }, 922 "PSmall": null, 923 "PPSmall": { 924 "Tag": "tag31" 925 }, 926 "Interface": null, 927 "PInterface": 5.2 928 }` 929 930 var pallValueCompact = strings.Map(noSpace, pallValueIndent) 931 932 func TestRefUnmarshal(t *testing.T) { 933 type S struct { 934 // Ref is defined in encode_test.go. 935 R0 Ref 936 R1 *Ref 937 } 938 want := S{ 939 R0: 12, 940 R1: new(Ref), 941 } 942 *want.R1 = 12 943 944 var got S 945 if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref"}`), &got); err != nil { 946 t.Fatalf("Unmarshal: %v", err) 947 } 948 if !reflect.DeepEqual(got, want) { 949 t.Errorf("got %+v, want %+v", got, want) 950 } 951 } 952 953 // Test that the empty string doesn't panic decoding when ,string is specified 954 // Issue 3450 955 func TestEmptyString(t *testing.T) { 956 type T2 struct { 957 Number1 int `json:",string"` 958 Number2 int `json:",string"` 959 } 960 data := `{"Number1":"1", "Number2":""}` 961 dec := NewDecoder(strings.NewReader(data)) 962 var t2 T2 963 err := dec.Decode(&t2) 964 if err == nil { 965 t.Fatal("Decode: did not return error") 966 } 967 if t2.Number1 != 1 { 968 t.Fatal("Decode: did not set Number1") 969 } 970 } 971 972 func intp(x int) *int { 973 p := new(int) 974 *p = x 975 return p 976 } 977 978 func intpp(x *int) **int { 979 pp := new(*int) 980 *pp = x 981 return pp 982 } 983 984 var interfaceSetTests = []struct { 985 pre interface{} 986 json string 987 post interface{} 988 }{ 989 {"foo", `"bar"`, "bar"}, 990 {"foo", `2`, 2.0}, 991 {"foo", `true`, true}, 992 {"foo", `null`, nil}, 993 994 {nil, `null`, nil}, 995 {new(int), `null`, nil}, 996 {(*int)(nil), `null`, nil}, 997 {new(*int), `null`, new(*int)}, 998 {(**int)(nil), `null`, nil}, 999 {intp(1), `null`, nil}, 1000 {intpp(nil), `null`, intpp(nil)}, 1001 {intpp(intp(1)), `null`, intpp(nil)}, 1002 } 1003 1004 func TestInterfaceSet(t *testing.T) { 1005 for _, tt := range interfaceSetTests { 1006 b := struct{ X interface{} }{tt.pre} 1007 blob := `{"X":` + tt.json + `}` 1008 if err := Unmarshal([]byte(blob), &b); err != nil { 1009 t.Errorf("Unmarshal %#q: %v", blob, err) 1010 continue 1011 } 1012 if !reflect.DeepEqual(b.X, tt.post) { 1013 t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post) 1014 } 1015 } 1016 } 1017 1018 // JSON null values should be ignored for primitives and string values instead of resulting in an error. 1019 // Issue 2540 1020 func TestUnmarshalNulls(t *testing.T) { 1021 jsonData := []byte(`{ 1022 "Bool" : null, 1023 "Int" : null, 1024 "Int8" : null, 1025 "Int16" : null, 1026 "Int32" : null, 1027 "Int64" : null, 1028 "Uint" : null, 1029 "Uint8" : null, 1030 "Uint16" : null, 1031 "Uint32" : null, 1032 "Uint64" : null, 1033 "Float32" : null, 1034 "Float64" : null, 1035 "String" : null}`) 1036 1037 nulls := All{ 1038 Bool: true, 1039 Int: 2, 1040 Int8: 3, 1041 Int16: 4, 1042 Int32: 5, 1043 Int64: 6, 1044 Uint: 7, 1045 Uint8: 8, 1046 Uint16: 9, 1047 Uint32: 10, 1048 Uint64: 11, 1049 Float32: 12.1, 1050 Float64: 13.1, 1051 String: "14"} 1052 1053 err := Unmarshal(jsonData, &nulls) 1054 if err != nil { 1055 t.Errorf("Unmarshal of null values failed: %v", err) 1056 } 1057 if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 || 1058 nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 || 1059 nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" { 1060 1061 t.Errorf("Unmarshal of null values affected primitives") 1062 } 1063 } 1064 1065 func TestStringKind(t *testing.T) { 1066 type stringKind string 1067 type aMap map[stringKind]int 1068 1069 var m1, m2 map[stringKind]int 1070 m1 = map[stringKind]int{ 1071 "foo": 42, 1072 } 1073 1074 data, err := Marshal(m1) 1075 if err != nil { 1076 t.Errorf("Unexpected error marshalling: %v", err) 1077 } 1078 1079 err = Unmarshal(data, &m2) 1080 if err != nil { 1081 t.Errorf("Unexpected error unmarshalling: %v", err) 1082 } 1083 1084 if !reflect.DeepEqual(m1, m2) { 1085 t.Error("Items should be equal after encoding and then decoding") 1086 } 1087 1088 } 1089 1090 var decodeTypeErrorTests = []struct { 1091 dest interface{} 1092 src string 1093 }{ 1094 {new(string), `{"user": "name"}`}, // issue 4628. 1095 {new(error), `{}`}, // issue 4222 1096 {new(error), `[]`}, 1097 {new(error), `""`}, 1098 {new(error), `123`}, 1099 {new(error), `true`}, 1100 } 1101 1102 func TestUnmarshalTypeError(t *testing.T) { 1103 for _, item := range decodeTypeErrorTests { 1104 err := Unmarshal([]byte(item.src), item.dest) 1105 if _, ok := err.(*UnmarshalTypeError); !ok { 1106 t.Errorf("expected type error for Unmarshal(%q, type %T): got %T", 1107 item.src, item.dest, err) 1108 } 1109 } 1110 } 1111 1112 var unmarshalSyntaxTests = []string{ 1113 "tru", 1114 "fals", 1115 "nul", 1116 "123e", 1117 `"hello`, 1118 `[1,2,3`, 1119 `{"key":1`, 1120 `{"key":1,`, 1121 } 1122 1123 func TestUnmarshalSyntax(t *testing.T) { 1124 var x interface{} 1125 for _, src := range unmarshalSyntaxTests { 1126 err := Unmarshal([]byte(src), &x) 1127 if _, ok := err.(*SyntaxError); !ok { 1128 t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err) 1129 } 1130 } 1131 } 1132 1133 // Test handling of unexported fields that should be ignored. 1134 // Issue 4660 1135 type unexportedFields struct { 1136 Name string 1137 m map[string]interface{} `json:"-"` 1138 m2 map[string]interface{} `json:"abcd"` 1139 } 1140 1141 func TestUnmarshalUnexported(t *testing.T) { 1142 input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}` 1143 want := &unexportedFields{Name: "Bob"} 1144 1145 out := &unexportedFields{} 1146 err := Unmarshal([]byte(input), out) 1147 if err != nil { 1148 t.Errorf("got error %v, expected nil", err) 1149 } 1150 if !reflect.DeepEqual(out, want) { 1151 t.Errorf("got %q, want %q", out, want) 1152 } 1153 } 1154 1155 // Time3339 is a time.Time which encodes to and from JSON 1156 // as an RFC 3339 time in UTC. 1157 type Time3339 time.Time 1158 1159 func (t *Time3339) UnmarshalJSON(b []byte) error { 1160 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { 1161 return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b) 1162 } 1163 tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1])) 1164 if err != nil { 1165 return err 1166 } 1167 *t = Time3339(tm) 1168 return nil 1169 } 1170 1171 func TestUnmarshalJSONLiteralError(t *testing.T) { 1172 var t3 Time3339 1173 err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3) 1174 if err == nil { 1175 t.Fatalf("expected error; got time %v", time.Time(t3)) 1176 } 1177 if !strings.Contains(err.Error(), "range") { 1178 t.Errorf("got err = %v; want out of range error", err) 1179 } 1180 } 1181 1182 // Test that extra object elements in an array do not result in a 1183 // "data changing underfoot" error. 1184 // Issue 3717 1185 func TestSkipArrayObjects(t *testing.T) { 1186 json := `[{}]` 1187 var dest [0]interface{} 1188 1189 err := Unmarshal([]byte(json), &dest) 1190 if err != nil { 1191 t.Errorf("got error %q, want nil", err) 1192 } 1193 }