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