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.
24 Alphabet
string `json:"alpha"`
33 // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and
35 var ifaceNumAsFloat64
= map[string]interface{}{
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{}{
45 "k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")},
46 "k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")},
53 var txType
= reflect
.TypeOf((*tx
)(nil)).Elem()
55 // A type that can unmarshal itself.
57 type unmarshaler
struct {
61 func (u
*unmarshaler
) UnmarshalJSON(b
[]byte) error
{
62 *u
= unmarshaler
{true} // All we need to see that UnmarshalJson is called.
71 um0
, um1 unmarshaler
// target2 of unmarshaling
73 umtrue
= unmarshaler
{true}
74 umslice
= []unmarshaler
{{true}}
75 umslicep
= new([]unmarshaler
)
76 umstruct
= ustruct
{unmarshaler
{true}}
79 // Test data structures for anonymous fields.
89 *Embed0b
`json:"e,omitempty"` // treated as named
90 Embed0c
`json:"-"` // ignored
92 Embed0p
// has Point with X, Y, used
93 Embed0q
// has Point with Z, used
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
116 type Embed0p
struct {
120 type Embed0q
struct {
125 Loop1
int `json:",omitempty"`
126 Loop2
int `json:",omitempty"`
130 // From reflect test:
131 // The X in S6 and S7 annihilate, but they also block the X in S8.S9.
153 // From reflect test:
154 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
173 type unmarshalTest
struct {
182 // Given "hello", the first match should win.
183 First
int `json:"HELLO"`
184 Second
int `json:"Hello"`
187 var unmarshalTests
= []unmarshalTest
{
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"},
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
{}},
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},
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}},
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)}},
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
},
310 Point
: image
.Point
{X
: 15, Y
: 16},
320 out
: Ambig
{First
: 1},
324 in
: `{"X": 1,"Y":2}`,
326 out
: S5
{S8
: S8
{S9
: S9
{Y
: 2}}},
329 in
: `{"X": 1,"Y":2}`,
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\"",
338 out
: "hello\ufffdworld",
341 in
: "\"hello\xc2\xc2world\"",
343 out
: "hello\ufffd\ufffdworld",
346 in
: "\"hello\xc2\xffworld\"",
348 out
: "hello\ufffd\ufffdworld",
351 in
: "\"hello\\ud800world\"",
353 out
: "hello\ufffdworld",
356 in
: "\"hello\\ud800\\ud800world\"",
358 out
: "hello\ufffd\ufffdworld",
361 in
: "\"hello\\ud800\\ud800world\"",
363 out
: "hello\ufffd\ufffdworld",
366 in
: "\"hello\xed\xa0\x80\xed\xb0\x80world\"",
368 out
: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld",
372 func TestMarshal(t
*testing
.T
) {
373 b
, err
:= Marshal(allValue
)
375 t
.Fatalf("Marshal allValue: %v", err
)
377 if string(b
) != allValueCompact
{
378 t
.Errorf("Marshal allValueCompact")
379 diff(t
, b
, []byte(allValueCompact
))
383 b
, err
= Marshal(pallValue
)
385 t
.Fatalf("Marshal pallValue: %v", err
)
387 if string(b
) != pallValueCompact
{
388 t
.Errorf("Marshal pallValueCompact")
389 diff(t
, b
, []byte(pallValueCompact
))
394 func TestMarshalBadUTF8(t
*testing
.T
) {
395 s
:= "hello\xffworld"
398 t
.Fatal("Marshal bad UTF8: no error")
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
) {
410 out
, err
:= Marshal(n
)
414 outStr
:= string(out
)
416 t
.Fatalf("Invalid zero val for Number: %q", outStr
)
420 func TestUnmarshal(t
*testing
.T
) {
421 for i
, tt
:= range unmarshalTests
{
424 if err
:= checkValid(in
, &scan
); err
!= nil {
425 if !reflect
.DeepEqual(err
, tt
.err
) {
426 t
.Errorf("#%d: checkValid: %#v", i
, err
)
433 // v = new(right-type)
434 v
:= reflect
.New(reflect
.TypeOf(tt
.ptr
).Elem())
435 dec
:= NewDecoder(bytes
.NewBuffer(in
))
439 if err
:= dec
.Decode(v
.Interface()); !reflect
.DeepEqual(err
, tt
.err
) {
440 t
.Errorf("#%d: %v want %v", i
, err
, tt
.err
)
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
))
454 enc
, err
:= Marshal(v
.Interface())
456 t
.Errorf("#%d: error re-marshaling: %v", i
, err
)
459 vv
:= reflect
.New(reflect
.TypeOf(tt
.ptr
).Elem())
460 dec
= NewDecoder(bytes
.NewBuffer(enc
))
464 if err
:= dec
.Decode(vv
.Interface()); err
!= nil {
465 t
.Errorf("#%d: error re-unmarshaling: %v", i
, err
)
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())
476 func TestUnmarshalMarshal(t
*testing
.T
) {
479 if err
:= Unmarshal(jsonBig
, &v
); err
!= nil {
480 t
.Fatalf("Unmarshal: %v", err
)
484 t
.Fatalf("Marshal: %v", err
)
486 if !bytes
.Equal(jsonBig
, b
) {
487 t
.Errorf("Marshal jsonBig")
493 var numberTests
= []struct {
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
{
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)
530 b
, err
:= Marshal(s0
)
532 t
.Fatalf("Marshal: %v", err
)
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")
548 func TestUnmarshalInterface(t
*testing
.T
) {
550 var i
interface{} = &xint
551 if err
:= Unmarshal([]byte(`{"X":1}`), &i
); err
!= nil {
552 t
.Fatalf("Unmarshal: %v", err
)
555 t
.Fatalf("Did not write to xint")
559 func TestUnmarshalPtrPtr(t
*testing
.T
) {
562 if err
:= Unmarshal([]byte(`{"X":1}`), &pxint
); err
!= nil {
563 t
.Fatalf("Unmarshal: %v", err
)
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
)
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 {
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
)
603 err
:= NewDecoder(r
).Decode(&s
)
604 got
:= fmt
.Sprintf("%v", err
)
606 t
.Errorf("%d. got err = %q, want %q", n
, got
, tt
.err
)
611 func noSpace(c rune
) rune
{
634 Foo
string `json:"bar"`
635 Foo2
string `json:"bar2,dummyopt"`
637 IntStr
int64 `json:",string"`
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
680 Interface
interface{}
681 PInterface
*interface{}
709 Map
: map[string]Small
{
710 "17": {Tag
: "tag17"},
711 "18": {Tag
: "tag18"},
713 MapP
: map[string]*Small
{
714 "19": {Tag
: "tag19"},
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"},
729 PBool
: &allValue
.Bool
,
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
,
745 PMapP
: &allValue
.MapP
,
746 PSlice
: &allValue
.Slice
,
747 PSliceP
: &allValue
.SliceP
,
748 PPSmall
: &allValue
.PSmall
,
749 PInterface
: &allValue
.Interface
,
752 var allValueIndent
= `{
842 var allValueCompact
= strings
.Map(noSpace
, allValueIndent
)
844 var pallValueIndent
= `{
930 var pallValueCompact
= strings
.Map(noSpace
, pallValueIndent
)
932 func TestRefUnmarshal(t
*testing
.T
) {
934 // Ref is defined in encode_test.go.
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
955 func TestEmptyString(t
*testing
.T
) {
957 Number1
int `json:",string"`
958 Number2
int `json:",string"`
960 data
:= `{"Number1":"1", "Number2":""}`
961 dec
:= NewDecoder(strings
.NewReader(data
))
963 err
:= dec
.Decode(&t2
)
965 t
.Fatal("Decode: did not return error")
968 t
.Fatal("Decode: did not set Number1")
972 func intp(x
int) *int {
978 func intpp(x
*int) **int {
984 var interfaceSetTests
= []struct {
989 {"foo", `"bar"`, "bar"},
991 {"foo", `true`, true},
992 {"foo", `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
)
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.
1020 func TestUnmarshalNulls(t
*testing
.T
) {
1021 jsonData
:= []byte(`{
1053 err
:= Unmarshal(jsonData
, &nulls
)
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{
1074 data
, err
:= Marshal(m1
)
1076 t
.Errorf("Unexpected error marshalling: %v", err
)
1079 err
= Unmarshal(data
, &m2
)
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 {
1094 {new(string), `{"user": "name"}`}, // issue 4628.
1095 {new(error
), `{}`}, // issue 4222
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{
1123 func TestUnmarshalSyntax(t
*testing
.T
) {
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.
1135 type unexportedFields
struct {
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
)
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]))
1171 func TestUnmarshalJSONLiteralError(t
*testing
.T
) {
1173 err
:= Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3
)
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.
1185 func TestSkipArrayObjects(t
*testing
.T
) {
1187 var dest
[0]interface{}
1189 err
:= Unmarshal([]byte(json
), &dest
)
1191 t
.Errorf("got error %q, want nil", err
)