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