libgo: Update to Go 1.1.1.
[official-gcc.git] / libgo / go / encoding / json / decode_test.go
blobf845f69ab7f4e7bb0cbfc83a98d4a425c36593f9
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.
5 package json
7 import (
8 "bytes"
9 "fmt"
10 "image"
11 "reflect"
12 "strings"
13 "testing"
14 "time"
17 type T struct {
18 X string
19 Y int
20 Z int `json:"-"`
23 type U struct {
24 Alphabet string `json:"alpha"`
27 type V struct {
28 F1 interface{}
29 F2 int32
30 F3 Number
33 // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and
34 // without UseNumber
35 var ifaceNumAsFloat64 = map[string]interface{}{
36 "k1": float64(1),
37 "k2": "s",
38 "k3": []interface{}{float64(1), float64(2.0), float64(3e-3)},
39 "k4": map[string]interface{}{"kk1": "s", "kk2": float64(2)},
42 var ifaceNumAsNumber = map[string]interface{}{
43 "k1": Number("1"),
44 "k2": "s",
45 "k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")},
46 "k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")},
49 type tx struct {
50 x int
53 var txType = reflect.TypeOf((*tx)(nil)).Elem()
55 // A type that can unmarshal itself.
57 type unmarshaler struct {
58 T bool
61 func (u *unmarshaler) UnmarshalJSON(b []byte) error {
62 *u = unmarshaler{true} // All we need to see that UnmarshalJson is called.
63 return nil
66 type ustruct struct {
67 M unmarshaler
70 var (
71 um0, um1 unmarshaler // target2 of unmarshaling
72 ump = &um1
73 umtrue = unmarshaler{true}
74 umslice = []unmarshaler{{true}}
75 umslicep = new([]unmarshaler)
76 umstruct = ustruct{unmarshaler{true}}
79 // Test data structures for anonymous fields.
81 type Point struct {
82 Z int
85 type Top struct {
86 Level0 int
87 Embed0
88 *Embed0a
89 *Embed0b `json:"e,omitempty"` // treated as named
90 Embed0c `json:"-"` // ignored
91 Loop
92 Embed0p // has Point with X, Y, used
93 Embed0q // has Point with Z, used
96 type Embed0 struct {
97 Level1a int // overridden by Embed0a's Level1a with json tag
98 Level1b int // used because Embed0a's Level1b is renamed
99 Level1c int // used because Embed0a's Level1c is ignored
100 Level1d int // annihilated by Embed0a's Level1d
101 Level1e int `json:"x"` // annihilated by Embed0a.Level1e
104 type Embed0a struct {
105 Level1a int `json:"Level1a,omitempty"`
106 Level1b int `json:"LEVEL1B,omitempty"`
107 Level1c int `json:"-"`
108 Level1d int // annihilated by Embed0's Level1d
109 Level1f int `json:"x"` // annihilated by Embed0's Level1e
112 type Embed0b Embed0
114 type Embed0c Embed0
116 type Embed0p struct {
117 image.Point
120 type Embed0q struct {
121 Point
124 type Loop struct {
125 Loop1 int `json:",omitempty"`
126 Loop2 int `json:",omitempty"`
127 *Loop
130 // From reflect test:
131 // The X in S6 and S7 annihilate, but they also block the X in S8.S9.
132 type S5 struct {
138 type S6 struct {
139 X int
142 type S7 S6
144 type S8 struct {
148 type S9 struct {
149 X int
150 Y int
153 // From reflect test:
154 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
155 type S10 struct {
161 type S11 struct {
165 type S12 struct {
169 type S13 struct {
173 type unmarshalTest struct {
174 in string
175 ptr interface{}
176 out interface{}
177 err error
178 useNumber bool
181 type Ambig struct {
182 // Given "hello", the first match should win.
183 First int `json:"HELLO"`
184 Second int `json:"Hello"`
187 var unmarshalTests = []unmarshalTest{
188 // basic types
189 {in: `true`, ptr: new(bool), out: true},
190 {in: `1`, ptr: new(int), out: 1},
191 {in: `1.2`, ptr: new(float64), out: 1.2},
192 {in: `-5`, ptr: new(int16), out: int16(-5)},
193 {in: `2`, ptr: new(Number), out: Number("2"), useNumber: true},
194 {in: `2`, ptr: new(Number), out: Number("2")},
195 {in: `2`, ptr: new(interface{}), out: float64(2.0)},
196 {in: `2`, ptr: new(interface{}), out: Number("2"), useNumber: true},
197 {in: `"a\u1234"`, ptr: new(string), out: "a\u1234"},
198 {in: `"http:\/\/"`, ptr: new(string), out: "http://"},
199 {in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"},
200 {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
201 {in: "null", ptr: new(interface{}), out: nil},
202 {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf("")}},
203 {in: `{"x": 1}`, ptr: new(tx), out: tx{}},
204 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},
205 {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true},
206 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsFloat64},
207 {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsNumber, useNumber: true},
209 // raw values with whitespace
210 {in: "\n true ", ptr: new(bool), out: true},
211 {in: "\t 1 ", ptr: new(int), out: 1},
212 {in: "\r 1.2 ", ptr: new(float64), out: 1.2},
213 {in: "\t -5 \n", ptr: new(int16), out: int16(-5)},
214 {in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"},
216 // Z has a "-" tag.
217 {in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}},
219 {in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}},
220 {in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}},
221 {in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}},
223 // syntax errors
224 {in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}},
225 {in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}},
226 {in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true},
228 // raw value errors
229 {in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
230 {in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}},
231 {in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
232 {in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}},
233 {in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
234 {in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}},
235 {in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
236 {in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}},
238 // array tests
239 {in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}},
240 {in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}},
241 {in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},
243 // empty array to interface test
244 {in: `[]`, ptr: new([]interface{}), out: []interface{}{}},
245 {in: `null`, ptr: new([]interface{}), out: []interface{}(nil)},
246 {in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}},
247 {in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}},
249 // composite tests
250 {in: allValueIndent, ptr: new(All), out: allValue},
251 {in: allValueCompact, ptr: new(All), out: allValue},
252 {in: allValueIndent, ptr: new(*All), out: &allValue},
253 {in: allValueCompact, ptr: new(*All), out: &allValue},
254 {in: pallValueIndent, ptr: new(All), out: pallValue},
255 {in: pallValueCompact, ptr: new(All), out: pallValue},
256 {in: pallValueIndent, ptr: new(*All), out: &pallValue},
257 {in: pallValueCompact, ptr: new(*All), out: &pallValue},
259 // unmarshal interface test
260 {in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called
261 {in: `{"T":false}`, ptr: &ump, out: &umtrue},
262 {in: `[{"T":false}]`, ptr: &umslice, out: umslice},
263 {in: `[{"T":false}]`, ptr: &umslicep, out: &umslice},
264 {in: `{"M":{"T":false}}`, ptr: &umstruct, out: umstruct},
267 in: `{
268 "Level0": 1,
269 "Level1b": 2,
270 "Level1c": 3,
271 "x": 4,
272 "Level1a": 5,
273 "LEVEL1B": 6,
274 "e": {
275 "Level1a": 8,
276 "Level1b": 9,
277 "Level1c": 10,
278 "Level1d": 11,
279 "x": 12
281 "Loop1": 13,
282 "Loop2": 14,
283 "X": 15,
284 "Y": 16,
285 "Z": 17
287 ptr: new(Top),
288 out: Top{
289 Level0: 1,
290 Embed0: Embed0{
291 Level1b: 2,
292 Level1c: 3,
294 Embed0a: &Embed0a{
295 Level1a: 5,
296 Level1b: 6,
298 Embed0b: &Embed0b{
299 Level1a: 8,
300 Level1b: 9,
301 Level1c: 10,
302 Level1d: 11,
303 Level1e: 12,
305 Loop: Loop{
306 Loop1: 13,
307 Loop2: 14,
309 Embed0p: Embed0p{
310 Point: image.Point{X: 15, Y: 16},
312 Embed0q: Embed0q{
313 Point: Point{Z: 17},
318 in: `{"hello": 1}`,
319 ptr: new(Ambig),
320 out: Ambig{First: 1},
324 in: `{"X": 1,"Y":2}`,
325 ptr: new(S5),
326 out: S5{S8: S8{S9: S9{Y: 2}}},
329 in: `{"X": 1,"Y":2}`,
330 ptr: new(S10),
331 out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
334 // invalid UTF-8 is coerced to valid UTF-8.
336 in: "\"hello\xffworld\"",
337 ptr: new(string),
338 out: "hello\ufffdworld",
341 in: "\"hello\xc2\xc2world\"",
342 ptr: new(string),
343 out: "hello\ufffd\ufffdworld",
346 in: "\"hello\xc2\xffworld\"",
347 ptr: new(string),
348 out: "hello\ufffd\ufffdworld",
351 in: "\"hello\\ud800world\"",
352 ptr: new(string),
353 out: "hello\ufffdworld",
356 in: "\"hello\\ud800\\ud800world\"",
357 ptr: new(string),
358 out: "hello\ufffd\ufffdworld",
361 in: "\"hello\\ud800\\ud800world\"",
362 ptr: new(string),
363 out: "hello\ufffd\ufffdworld",
366 in: "\"hello\xed\xa0\x80\xed\xb0\x80world\"",
367 ptr: new(string),
368 out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld",
372 func TestMarshal(t *testing.T) {
373 b, err := Marshal(allValue)
374 if err != nil {
375 t.Fatalf("Marshal allValue: %v", err)
377 if string(b) != allValueCompact {
378 t.Errorf("Marshal allValueCompact")
379 diff(t, b, []byte(allValueCompact))
380 return
383 b, err = Marshal(pallValue)
384 if err != nil {
385 t.Fatalf("Marshal pallValue: %v", err)
387 if string(b) != pallValueCompact {
388 t.Errorf("Marshal pallValueCompact")
389 diff(t, b, []byte(pallValueCompact))
390 return
394 func TestMarshalBadUTF8(t *testing.T) {
395 s := "hello\xffworld"
396 b, err := Marshal(s)
397 if err == nil {
398 t.Fatal("Marshal bad UTF8: no error")
400 if len(b) != 0 {
401 t.Fatal("Marshal returned data")
403 if _, ok := err.(*InvalidUTF8Error); !ok {
404 t.Fatalf("Marshal did not return InvalidUTF8Error: %T %v", err, err)
408 func TestMarshalNumberZeroVal(t *testing.T) {
409 var n Number
410 out, err := Marshal(n)
411 if err != nil {
412 t.Fatal(err)
414 outStr := string(out)
415 if outStr != "0" {
416 t.Fatalf("Invalid zero val for Number: %q", outStr)
420 func TestUnmarshal(t *testing.T) {
421 for i, tt := range unmarshalTests {
422 var scan scanner
423 in := []byte(tt.in)
424 if err := checkValid(in, &scan); err != nil {
425 if !reflect.DeepEqual(err, tt.err) {
426 t.Errorf("#%d: checkValid: %#v", i, err)
427 continue
430 if tt.ptr == nil {
431 continue
433 // v = new(right-type)
434 v := reflect.New(reflect.TypeOf(tt.ptr).Elem())
435 dec := NewDecoder(bytes.NewBuffer(in))
436 if tt.useNumber {
437 dec.UseNumber()
439 if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) {
440 t.Errorf("#%d: %v want %v", i, err, tt.err)
441 continue
443 if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
444 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out)
445 data, _ := Marshal(v.Elem().Interface())
446 println(string(data))
447 data, _ = Marshal(tt.out)
448 println(string(data))
449 continue
452 // Check round trip.
453 if tt.err == nil {
454 enc, err := Marshal(v.Interface())
455 if err != nil {
456 t.Errorf("#%d: error re-marshaling: %v", i, err)
457 continue
459 vv := reflect.New(reflect.TypeOf(tt.ptr).Elem())
460 dec = NewDecoder(bytes.NewBuffer(enc))
461 if tt.useNumber {
462 dec.UseNumber()
464 if err := dec.Decode(vv.Interface()); err != nil {
465 t.Errorf("#%d: error re-unmarshaling: %v", i, err)
466 continue
468 if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) {
469 t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface())
470 continue
476 func TestUnmarshalMarshal(t *testing.T) {
477 initBig()
478 var v interface{}
479 if err := Unmarshal(jsonBig, &v); err != nil {
480 t.Fatalf("Unmarshal: %v", err)
482 b, err := Marshal(v)
483 if err != nil {
484 t.Fatalf("Marshal: %v", err)
486 if !bytes.Equal(jsonBig, b) {
487 t.Errorf("Marshal jsonBig")
488 diff(t, b, jsonBig)
489 return
493 var numberTests = []struct {
494 in string
495 i int64
496 intErr string
497 f float64
498 floatErr string
500 {in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1},
501 {in: "-12", i: -12, f: -12.0},
502 {in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"},
505 // Independent of Decode, basic coverage of the accessors in Number
506 func TestNumberAccessors(t *testing.T) {
507 for _, tt := range numberTests {
508 n := Number(tt.in)
509 if s := n.String(); s != tt.in {
510 t.Errorf("Number(%q).String() is %q", tt.in, s)
512 if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i {
513 t.Errorf("Number(%q).Int64() is %d", tt.in, i)
514 } else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) {
515 t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err)
517 if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f {
518 t.Errorf("Number(%q).Float64() is %g", tt.in, f)
519 } else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) {
520 t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err)
525 func TestLargeByteSlice(t *testing.T) {
526 s0 := make([]byte, 2000)
527 for i := range s0 {
528 s0[i] = byte(i)
530 b, err := Marshal(s0)
531 if err != nil {
532 t.Fatalf("Marshal: %v", err)
534 var s1 []byte
535 if err := Unmarshal(b, &s1); err != nil {
536 t.Fatalf("Unmarshal: %v", err)
538 if !bytes.Equal(s0, s1) {
539 t.Errorf("Marshal large byte slice")
540 diff(t, s0, s1)
544 type Xint struct {
545 X int
548 func TestUnmarshalInterface(t *testing.T) {
549 var xint Xint
550 var i interface{} = &xint
551 if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil {
552 t.Fatalf("Unmarshal: %v", err)
554 if xint.X != 1 {
555 t.Fatalf("Did not write to xint")
559 func TestUnmarshalPtrPtr(t *testing.T) {
560 var xint Xint
561 pxint := &xint
562 if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil {
563 t.Fatalf("Unmarshal: %v", err)
565 if xint.X != 1 {
566 t.Fatalf("Did not write to xint")
570 func TestEscape(t *testing.T) {
571 const input = `"foobar"<html>`
572 const expected = `"\"foobar\"\u003chtml\u003e"`
573 b, err := Marshal(input)
574 if err != nil {
575 t.Fatalf("Marshal error: %v", err)
577 if s := string(b); s != expected {
578 t.Errorf("Encoding of [%s] was [%s], want [%s]", input, s, expected)
582 // WrongString is a struct that's misusing the ,string modifier.
583 type WrongString struct {
584 Message string `json:"result,string"`
587 type wrongStringTest struct {
588 in, err string
591 var wrongStringTests = []wrongStringTest{
592 {`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`},
593 {`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`},
594 {`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`},
597 // If people misuse the ,string modifier, the error message should be
598 // helpful, telling the user that they're doing it wrong.
599 func TestErrorMessageFromMisusedString(t *testing.T) {
600 for n, tt := range wrongStringTests {
601 r := strings.NewReader(tt.in)
602 var s WrongString
603 err := NewDecoder(r).Decode(&s)
604 got := fmt.Sprintf("%v", err)
605 if got != tt.err {
606 t.Errorf("%d. got err = %q, want %q", n, got, tt.err)
611 func noSpace(c rune) rune {
612 if isSpace(c) {
613 return -1
615 return c
618 type All struct {
619 Bool bool
620 Int int
621 Int8 int8
622 Int16 int16
623 Int32 int32
624 Int64 int64
625 Uint uint
626 Uint8 uint8
627 Uint16 uint16
628 Uint32 uint32
629 Uint64 uint64
630 Uintptr uintptr
631 Float32 float32
632 Float64 float64
634 Foo string `json:"bar"`
635 Foo2 string `json:"bar2,dummyopt"`
637 IntStr int64 `json:",string"`
639 PBool *bool
640 PInt *int
641 PInt8 *int8
642 PInt16 *int16
643 PInt32 *int32
644 PInt64 *int64
645 PUint *uint
646 PUint8 *uint8
647 PUint16 *uint16
648 PUint32 *uint32
649 PUint64 *uint64
650 PUintptr *uintptr
651 PFloat32 *float32
652 PFloat64 *float64
654 String string
655 PString *string
657 Map map[string]Small
658 MapP map[string]*Small
659 PMap *map[string]Small
660 PMapP *map[string]*Small
662 EmptyMap map[string]Small
663 NilMap map[string]Small
665 Slice []Small
666 SliceP []*Small
667 PSlice *[]Small
668 PSliceP *[]*Small
670 EmptySlice []Small
671 NilSlice []Small
673 StringSlice []string
674 ByteSlice []byte
676 Small Small
677 PSmall *Small
678 PPSmall **Small
680 Interface interface{}
681 PInterface *interface{}
683 unexported int
686 type Small struct {
687 Tag string
690 var allValue = All{
691 Bool: true,
692 Int: 2,
693 Int8: 3,
694 Int16: 4,
695 Int32: 5,
696 Int64: 6,
697 Uint: 7,
698 Uint8: 8,
699 Uint16: 9,
700 Uint32: 10,
701 Uint64: 11,
702 Uintptr: 12,
703 Float32: 14.1,
704 Float64: 15.1,
705 Foo: "foo",
706 Foo2: "foo2",
707 IntStr: 42,
708 String: "16",
709 Map: map[string]Small{
710 "17": {Tag: "tag17"},
711 "18": {Tag: "tag18"},
713 MapP: map[string]*Small{
714 "19": {Tag: "tag19"},
715 "20": nil,
717 EmptyMap: map[string]Small{},
718 Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}},
719 SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}},
720 EmptySlice: []Small{},
721 StringSlice: []string{"str24", "str25", "str26"},
722 ByteSlice: []byte{27, 28, 29},
723 Small: Small{Tag: "tag30"},
724 PSmall: &Small{Tag: "tag31"},
725 Interface: 5.2,
728 var pallValue = All{
729 PBool: &allValue.Bool,
730 PInt: &allValue.Int,
731 PInt8: &allValue.Int8,
732 PInt16: &allValue.Int16,
733 PInt32: &allValue.Int32,
734 PInt64: &allValue.Int64,
735 PUint: &allValue.Uint,
736 PUint8: &allValue.Uint8,
737 PUint16: &allValue.Uint16,
738 PUint32: &allValue.Uint32,
739 PUint64: &allValue.Uint64,
740 PUintptr: &allValue.Uintptr,
741 PFloat32: &allValue.Float32,
742 PFloat64: &allValue.Float64,
743 PString: &allValue.String,
744 PMap: &allValue.Map,
745 PMapP: &allValue.MapP,
746 PSlice: &allValue.Slice,
747 PSliceP: &allValue.SliceP,
748 PPSmall: &allValue.PSmall,
749 PInterface: &allValue.Interface,
752 var allValueIndent = `{
753 "Bool": true,
754 "Int": 2,
755 "Int8": 3,
756 "Int16": 4,
757 "Int32": 5,
758 "Int64": 6,
759 "Uint": 7,
760 "Uint8": 8,
761 "Uint16": 9,
762 "Uint32": 10,
763 "Uint64": 11,
764 "Uintptr": 12,
765 "Float32": 14.1,
766 "Float64": 15.1,
767 "bar": "foo",
768 "bar2": "foo2",
769 "IntStr": "42",
770 "PBool": null,
771 "PInt": null,
772 "PInt8": null,
773 "PInt16": null,
774 "PInt32": null,
775 "PInt64": null,
776 "PUint": null,
777 "PUint8": null,
778 "PUint16": null,
779 "PUint32": null,
780 "PUint64": null,
781 "PUintptr": null,
782 "PFloat32": null,
783 "PFloat64": null,
784 "String": "16",
785 "PString": null,
786 "Map": {
787 "17": {
788 "Tag": "tag17"
790 "18": {
791 "Tag": "tag18"
794 "MapP": {
795 "19": {
796 "Tag": "tag19"
798 "20": null
800 "PMap": null,
801 "PMapP": null,
802 "EmptyMap": {},
803 "NilMap": null,
804 "Slice": [
806 "Tag": "tag20"
809 "Tag": "tag21"
812 "SliceP": [
814 "Tag": "tag22"
816 null,
818 "Tag": "tag23"
821 "PSlice": null,
822 "PSliceP": null,
823 "EmptySlice": [],
824 "NilSlice": null,
825 "StringSlice": [
826 "str24",
827 "str25",
828 "str26"
830 "ByteSlice": "Gxwd",
831 "Small": {
832 "Tag": "tag30"
834 "PSmall": {
835 "Tag": "tag31"
837 "PPSmall": null,
838 "Interface": 5.2,
839 "PInterface": null
842 var allValueCompact = strings.Map(noSpace, allValueIndent)
844 var pallValueIndent = `{
845 "Bool": false,
846 "Int": 0,
847 "Int8": 0,
848 "Int16": 0,
849 "Int32": 0,
850 "Int64": 0,
851 "Uint": 0,
852 "Uint8": 0,
853 "Uint16": 0,
854 "Uint32": 0,
855 "Uint64": 0,
856 "Uintptr": 0,
857 "Float32": 0,
858 "Float64": 0,
859 "bar": "",
860 "bar2": "",
861 "IntStr": "0",
862 "PBool": true,
863 "PInt": 2,
864 "PInt8": 3,
865 "PInt16": 4,
866 "PInt32": 5,
867 "PInt64": 6,
868 "PUint": 7,
869 "PUint8": 8,
870 "PUint16": 9,
871 "PUint32": 10,
872 "PUint64": 11,
873 "PUintptr": 12,
874 "PFloat32": 14.1,
875 "PFloat64": 15.1,
876 "String": "",
877 "PString": "16",
878 "Map": null,
879 "MapP": null,
880 "PMap": {
881 "17": {
882 "Tag": "tag17"
884 "18": {
885 "Tag": "tag18"
888 "PMapP": {
889 "19": {
890 "Tag": "tag19"
892 "20": null
894 "EmptyMap": null,
895 "NilMap": null,
896 "Slice": null,
897 "SliceP": null,
898 "PSlice": [
900 "Tag": "tag20"
903 "Tag": "tag21"
906 "PSliceP": [
908 "Tag": "tag22"
910 null,
912 "Tag": "tag23"
915 "EmptySlice": null,
916 "NilSlice": null,
917 "StringSlice": null,
918 "ByteSlice": null,
919 "Small": {
920 "Tag": ""
922 "PSmall": null,
923 "PPSmall": {
924 "Tag": "tag31"
926 "Interface": null,
927 "PInterface": 5.2
930 var pallValueCompact = strings.Map(noSpace, pallValueIndent)
932 func TestRefUnmarshal(t *testing.T) {
933 type S struct {
934 // Ref is defined in encode_test.go.
935 R0 Ref
936 R1 *Ref
938 want := S{
939 R0: 12,
940 R1: new(Ref),
942 *want.R1 = 12
944 var got S
945 if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref"}`), &got); err != nil {
946 t.Fatalf("Unmarshal: %v", err)
948 if !reflect.DeepEqual(got, want) {
949 t.Errorf("got %+v, want %+v", got, want)
953 // Test that the empty string doesn't panic decoding when ,string is specified
954 // Issue 3450
955 func TestEmptyString(t *testing.T) {
956 type T2 struct {
957 Number1 int `json:",string"`
958 Number2 int `json:",string"`
960 data := `{"Number1":"1", "Number2":""}`
961 dec := NewDecoder(strings.NewReader(data))
962 var t2 T2
963 err := dec.Decode(&t2)
964 if err == nil {
965 t.Fatal("Decode: did not return error")
967 if t2.Number1 != 1 {
968 t.Fatal("Decode: did not set Number1")
972 func intp(x int) *int {
973 p := new(int)
974 *p = x
975 return p
978 func intpp(x *int) **int {
979 pp := new(*int)
980 *pp = x
981 return pp
984 var interfaceSetTests = []struct {
985 pre interface{}
986 json string
987 post interface{}
989 {"foo", `"bar"`, "bar"},
990 {"foo", `2`, 2.0},
991 {"foo", `true`, true},
992 {"foo", `null`, nil},
994 {nil, `null`, nil},
995 {new(int), `null`, nil},
996 {(*int)(nil), `null`, nil},
997 {new(*int), `null`, new(*int)},
998 {(**int)(nil), `null`, nil},
999 {intp(1), `null`, nil},
1000 {intpp(nil), `null`, intpp(nil)},
1001 {intpp(intp(1)), `null`, intpp(nil)},
1004 func TestInterfaceSet(t *testing.T) {
1005 for _, tt := range interfaceSetTests {
1006 b := struct{ X interface{} }{tt.pre}
1007 blob := `{"X":` + tt.json + `}`
1008 if err := Unmarshal([]byte(blob), &b); err != nil {
1009 t.Errorf("Unmarshal %#q: %v", blob, err)
1010 continue
1012 if !reflect.DeepEqual(b.X, tt.post) {
1013 t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post)
1018 // JSON null values should be ignored for primitives and string values instead of resulting in an error.
1019 // Issue 2540
1020 func TestUnmarshalNulls(t *testing.T) {
1021 jsonData := []byte(`{
1022 "Bool" : null,
1023 "Int" : null,
1024 "Int8" : null,
1025 "Int16" : null,
1026 "Int32" : null,
1027 "Int64" : null,
1028 "Uint" : null,
1029 "Uint8" : null,
1030 "Uint16" : null,
1031 "Uint32" : null,
1032 "Uint64" : null,
1033 "Float32" : null,
1034 "Float64" : null,
1035 "String" : null}`)
1037 nulls := All{
1038 Bool: true,
1039 Int: 2,
1040 Int8: 3,
1041 Int16: 4,
1042 Int32: 5,
1043 Int64: 6,
1044 Uint: 7,
1045 Uint8: 8,
1046 Uint16: 9,
1047 Uint32: 10,
1048 Uint64: 11,
1049 Float32: 12.1,
1050 Float64: 13.1,
1051 String: "14"}
1053 err := Unmarshal(jsonData, &nulls)
1054 if err != nil {
1055 t.Errorf("Unmarshal of null values failed: %v", err)
1057 if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 ||
1058 nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 ||
1059 nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" {
1061 t.Errorf("Unmarshal of null values affected primitives")
1065 func TestStringKind(t *testing.T) {
1066 type stringKind string
1067 type aMap map[stringKind]int
1069 var m1, m2 map[stringKind]int
1070 m1 = map[stringKind]int{
1071 "foo": 42,
1074 data, err := Marshal(m1)
1075 if err != nil {
1076 t.Errorf("Unexpected error marshalling: %v", err)
1079 err = Unmarshal(data, &m2)
1080 if err != nil {
1081 t.Errorf("Unexpected error unmarshalling: %v", err)
1084 if !reflect.DeepEqual(m1, m2) {
1085 t.Error("Items should be equal after encoding and then decoding")
1090 var decodeTypeErrorTests = []struct {
1091 dest interface{}
1092 src string
1094 {new(string), `{"user": "name"}`}, // issue 4628.
1095 {new(error), `{}`}, // issue 4222
1096 {new(error), `[]`},
1097 {new(error), `""`},
1098 {new(error), `123`},
1099 {new(error), `true`},
1102 func TestUnmarshalTypeError(t *testing.T) {
1103 for _, item := range decodeTypeErrorTests {
1104 err := Unmarshal([]byte(item.src), item.dest)
1105 if _, ok := err.(*UnmarshalTypeError); !ok {
1106 t.Errorf("expected type error for Unmarshal(%q, type %T): got %T",
1107 item.src, item.dest, err)
1112 var unmarshalSyntaxTests = []string{
1113 "tru",
1114 "fals",
1115 "nul",
1116 "123e",
1117 `"hello`,
1118 `[1,2,3`,
1119 `{"key":1`,
1120 `{"key":1,`,
1123 func TestUnmarshalSyntax(t *testing.T) {
1124 var x interface{}
1125 for _, src := range unmarshalSyntaxTests {
1126 err := Unmarshal([]byte(src), &x)
1127 if _, ok := err.(*SyntaxError); !ok {
1128 t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err)
1133 // Test handling of unexported fields that should be ignored.
1134 // Issue 4660
1135 type unexportedFields struct {
1136 Name string
1137 m map[string]interface{} `json:"-"`
1138 m2 map[string]interface{} `json:"abcd"`
1141 func TestUnmarshalUnexported(t *testing.T) {
1142 input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}`
1143 want := &unexportedFields{Name: "Bob"}
1145 out := &unexportedFields{}
1146 err := Unmarshal([]byte(input), out)
1147 if err != nil {
1148 t.Errorf("got error %v, expected nil", err)
1150 if !reflect.DeepEqual(out, want) {
1151 t.Errorf("got %q, want %q", out, want)
1155 // Time3339 is a time.Time which encodes to and from JSON
1156 // as an RFC 3339 time in UTC.
1157 type Time3339 time.Time
1159 func (t *Time3339) UnmarshalJSON(b []byte) error {
1160 if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
1161 return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b)
1163 tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1]))
1164 if err != nil {
1165 return err
1167 *t = Time3339(tm)
1168 return nil
1171 func TestUnmarshalJSONLiteralError(t *testing.T) {
1172 var t3 Time3339
1173 err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3)
1174 if err == nil {
1175 t.Fatalf("expected error; got time %v", time.Time(t3))
1177 if !strings.Contains(err.Error(), "range") {
1178 t.Errorf("got err = %v; want out of range error", err)
1182 // Test that extra object elements in an array do not result in a
1183 // "data changing underfoot" error.
1184 // Issue 3717
1185 func TestSkipArrayObjects(t *testing.T) {
1186 json := `[{}]`
1187 var dest [0]interface{}
1189 err := Unmarshal([]byte(json), &dest)
1190 if err != nil {
1191 t.Errorf("got error %q, want nil", err)