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