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