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