diff options
Diffstat (limited to 'src/pkg/json/decode_test.go')
-rw-r--r-- | src/pkg/json/decode_test.go | 488 |
1 files changed, 391 insertions, 97 deletions
diff --git a/src/pkg/json/decode_test.go b/src/pkg/json/decode_test.go index b712d6558..288bb1b40 100644 --- a/src/pkg/json/decode_test.go +++ b/src/pkg/json/decode_test.go @@ -1,133 +1,427 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package json import ( - "container/vector" + "bytes" "reflect" + "strings" "testing" ) -func TestDecodeInt64(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Int64(-15) - assertResult(t, nb.Data(), float64(-15)) +type unmarshalTest struct { + in string + ptr interface{} + out interface{} } -func TestDecodeUint64(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Uint64(15) - assertResult(t, nb.Data(), float64(15)) -} +var unmarshalTests = []unmarshalTest{ + // basic types + unmarshalTest{`true`, new(bool), true}, + unmarshalTest{`1`, new(int), 1}, + unmarshalTest{`1.2`, new(float), 1.2}, + unmarshalTest{`-5`, new(int16), int16(-5)}, + unmarshalTest{`"a\u1234"`, new(string), "a\u1234"}, + unmarshalTest{`"g-clef: \uD834\uDD1E"`, new(string), "g-clef: \U0001D11E"}, + unmarshalTest{`"invalid: \uD834x\uDD1E"`, new(string), "invalid: \uFFFDx\uFFFD"}, + unmarshalTest{"null", new(interface{}), nil}, -func TestDecodeFloat64(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Float64(3.14159) - assertResult(t, nb.Data(), float64(3.14159)) + // composite tests + unmarshalTest{allValueIndent, new(All), allValue}, + unmarshalTest{allValueCompact, new(All), allValue}, + unmarshalTest{allValueIndent, new(*All), &allValue}, + unmarshalTest{allValueCompact, new(*All), &allValue}, + unmarshalTest{pallValueIndent, new(All), pallValue}, + unmarshalTest{pallValueCompact, new(All), pallValue}, + unmarshalTest{pallValueIndent, new(*All), &pallValue}, + unmarshalTest{pallValueCompact, new(*All), &pallValue}, } -func TestDecodeString(t *testing.T) { - nb := newDecoder(nil, nil) - nb.String("Some string") - assertResult(t, nb.Data(), "Some string") -} +func TestMarshal(t *testing.T) { + b, err := Marshal(allValue) + if err != nil { + t.Fatalf("Marshal allValue: %v", err) + } + if string(b) != allValueCompact { + t.Errorf("Marshal allValueCompact") + diff(t, b, []byte(allValueCompact)) + return + } -func TestDecodeBool(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Bool(true) - assertResult(t, nb.Data(), true) + b, err = Marshal(pallValue) + if err != nil { + t.Fatalf("Marshal pallValue: %v", err) + } + if string(b) != pallValueCompact { + t.Errorf("Marshal pallValueCompact") + diff(t, b, []byte(pallValueCompact)) + return + } } -func TestDecodeNull(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Null() - assertResult(t, nb.Data(), nil) +func TestUnmarshal(t *testing.T) { + var scan scanner + for i, tt := range unmarshalTests { + in := []byte(tt.in) + if err := checkValid(in, &scan); err != nil { + t.Errorf("#%d: checkValid: %v", i, err) + continue + } + // v = new(right-type) + v := reflect.NewValue(tt.ptr).(*reflect.PtrValue) + v.PointTo(reflect.MakeZero(v.Type().(*reflect.PtrType).Elem())) + if err := Unmarshal([]byte(in), v.Interface()); err != nil { + t.Errorf("#%d: %v", i, err) + continue + } + if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { + t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) + data, _ := Marshal(v.Elem().Interface()) + println(string(data)) + data, _ = Marshal(tt.out) + println(string(data)) + return + continue + } + } } -func TestDecodeEmptyArray(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Array() - assertResult(t, nb.Data(), []interface{}{}) +func TestUnmarshalMarshal(t *testing.T) { + var v interface{} + if err := Unmarshal(jsonBig, &v); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + b, err := Marshal(v) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if bytes.Compare(jsonBig, b) != 0 { + t.Errorf("Marshal jsonBig") + diff(t, b, jsonBig) + return + } } -func TestDecodeEmptyMap(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Map() - assertResult(t, nb.Data(), map[string]interface{}{}) +func noSpace(c int) int { + if isSpace(c) { + return -1 + } + return c } -func TestDecodeFlushElem(t *testing.T) { - testVec := new(vector.Vector).Resize(2, 2) - nb := newDecoder(testVec, 1) - nb.Float64(3.14159) - nb.Flush() - assertResult(t, testVec.Data(), []interface{}{nil, float64(3.14159)}) -} +type All struct { + Bool bool + Int int + Int8 int8 + Int16 int16 + Int32 int32 + Int64 int64 + Uint uint + Uint8 uint8 + Uint16 uint16 + Uint32 uint32 + Uint64 uint64 + Uintptr uintptr + Float float + Float32 float32 + Float64 float64 -func TestDecodeFlushKey(t *testing.T) { - testMap := make(map[string]interface{}) - nb := newDecoder(testMap, "key") - nb.Float64(3.14159) - nb.Flush() - assertResult(t, testMap, map[string]interface{}{"key": float64(3.14159)}) -} + Foo string "bar" -// Elem() and Key() are hard to test in isolation because all they do -// is create a new, properly initialized, decoder, and modify state of -// the underlying decoder. I'm testing them through already tested -// Array(), String(), and Flush(). - -func TestDecodeElem(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Array() - var b Builder = nb.Elem(0) - b.String("0") - b.Flush() - assertResult(t, nb.Data(), []interface{}{"0"}) -} + PBool *bool + PInt *int + PInt8 *int8 + PInt16 *int16 + PInt32 *int32 + PInt64 *int64 + PUint *uint + PUint8 *uint8 + PUint16 *uint16 + PUint32 *uint32 + PUint64 *uint64 + PUintptr *uintptr + PFloat *float + PFloat32 *float32 + PFloat64 *float64 + + String string + PString *string -func TestDecodeKey(t *testing.T) { - nb := newDecoder(nil, nil) - nb.Map() - var b Builder = nb.Key("a") - b.String("0") - b.Flush() - assertResult(t, nb.Data(), map[string]interface{}{"a": "0"}) + Map map[string]Small + MapP map[string]*Small + PMap *map[string]Small + PMapP *map[string]*Small + + EmptyMap map[string]Small + NilMap map[string]Small + + Slice []Small + SliceP []*Small + PSlice *[]Small + PSliceP *[]*Small + + EmptySlice []Small + NilSlice []Small + + StringSlice []string + ByteSlice []byte + + Small Small + PSmall *Small + PPSmall **Small + + Interface interface{} + PInterface *interface{} } -func assertResult(t *testing.T, results, expected interface{}) { - if !reflect.DeepEqual(results, expected) { - t.Fatalf("have %T(%#v) want %T(%#v)", results, results, expected, expected) - } +type Small struct { + Tag string } -type decodeTest struct { - s string - r interface{} +var allValue = All{ + Bool: true, + Int: 2, + Int8: 3, + Int16: 4, + Int32: 5, + Int64: 6, + Uint: 7, + Uint8: 8, + Uint16: 9, + Uint32: 10, + Uint64: 11, + Uintptr: 12, + Float: 13.1, + Float32: 14.1, + Float64: 15.1, + Foo: "foo", + String: "16", + Map: map[string]Small{ + "17": Small{Tag: "tag17"}, + "18": Small{Tag: "tag18"}, + }, + MapP: map[string]*Small{ + "19": &Small{Tag: "tag19"}, + "20": nil, + }, + EmptyMap: map[string]Small{}, + Slice: []Small{Small{Tag: "tag20"}, Small{Tag: "tag21"}}, + SliceP: []*Small{&Small{Tag: "tag22"}, nil, &Small{Tag: "tag23"}}, + EmptySlice: []Small{}, + StringSlice: []string{"str24", "str25", "str26"}, + ByteSlice: []byte{27, 28, 29}, + Small: Small{Tag: "tag30"}, + PSmall: &Small{Tag: "tag31"}, + Interface: float64(5.2), } -var tests = []decodeTest{ - decodeTest{`null`, nil}, - decodeTest{`true`, true}, - decodeTest{`false`, false}, - decodeTest{`"abc"`, "abc"}, - decodeTest{`123`, float64(123)}, - decodeTest{`0.1`, float64(0.1)}, - decodeTest{`1e-10`, float64(1e-10)}, - decodeTest{`[]`, []interface{}{}}, - decodeTest{`[1,2,3,4]`, []interface{}{float64(1), float64(2), float64(3), float64(4)}}, - decodeTest{`[1,2,"abc",null,true,false]`, []interface{}{float64(1), float64(2), "abc", nil, true, false}}, - decodeTest{`{}`, map[string]interface{}{}}, - decodeTest{`{"a":1}`, map[string]interface{}{"a": float64(1)}}, - decodeTest{`"q\u0302"`, "q\u0302"}, +var pallValue = All{ + PBool: &allValue.Bool, + PInt: &allValue.Int, + PInt8: &allValue.Int8, + PInt16: &allValue.Int16, + PInt32: &allValue.Int32, + PInt64: &allValue.Int64, + PUint: &allValue.Uint, + PUint8: &allValue.Uint8, + PUint16: &allValue.Uint16, + PUint32: &allValue.Uint32, + PUint64: &allValue.Uint64, + PUintptr: &allValue.Uintptr, + PFloat: &allValue.Float, + PFloat32: &allValue.Float32, + PFloat64: &allValue.Float64, + PString: &allValue.String, + PMap: &allValue.Map, + PMapP: &allValue.MapP, + PSlice: &allValue.Slice, + PSliceP: &allValue.SliceP, + PPSmall: &allValue.PSmall, + PInterface: &allValue.Interface, } -func TestDecode(t *testing.T) { - for _, test := range tests { - if val, err := Decode(test.s); err != nil || !reflect.DeepEqual(val, test.r) { - t.Errorf("Decode(%#q) = %v, %v want %v, nil", test.s, val, err, test.r) +var allValueIndent = `{ + "bool": true, + "int": 2, + "int8": 3, + "int16": 4, + "int32": 5, + "int64": 6, + "uint": 7, + "uint8": 8, + "uint16": 9, + "uint32": 10, + "uint64": 11, + "uintptr": 12, + "float": 13.1, + "float32": 14.1, + "float64": 15.1, + "bar": "foo", + "pbool": null, + "pint": null, + "pint8": null, + "pint16": null, + "pint32": null, + "pint64": null, + "puint": null, + "puint8": null, + "puint16": null, + "puint32": null, + "puint64": null, + "puintptr": null, + "pfloat": null, + "pfloat32": null, + "pfloat64": null, + "string": "16", + "pstring": null, + "map": { + "17": { + "tag": "tag17" + }, + "18": { + "tag": "tag18" } - } -} + }, + "mapp": { + "19": { + "tag": "tag19" + }, + "20": null + }, + "pmap": null, + "pmapp": null, + "emptymap": {}, + "nilmap": null, + "slice": [ + { + "tag": "tag20" + }, + { + "tag": "tag21" + } + ], + "slicep": [ + { + "tag": "tag22" + }, + null, + { + "tag": "tag23" + } + ], + "pslice": null, + "pslicep": null, + "emptyslice": [], + "nilslice": [], + "stringslice": [ + "str24", + "str25", + "str26" + ], + "byteslice": [ + 27, + 28, + 29 + ], + "small": { + "tag": "tag30" + }, + "psmall": { + "tag": "tag31" + }, + "ppsmall": null, + "interface": 5.2, + "pinterface": null +}` + +var allValueCompact = strings.Map(noSpace, allValueIndent) + +var pallValueIndent = `{ + "bool": false, + "int": 0, + "int8": 0, + "int16": 0, + "int32": 0, + "int64": 0, + "uint": 0, + "uint8": 0, + "uint16": 0, + "uint32": 0, + "uint64": 0, + "uintptr": 0, + "float": 0, + "float32": 0, + "float64": 0, + "bar": "", + "pbool": true, + "pint": 2, + "pint8": 3, + "pint16": 4, + "pint32": 5, + "pint64": 6, + "puint": 7, + "puint8": 8, + "puint16": 9, + "puint32": 10, + "puint64": 11, + "puintptr": 12, + "pfloat": 13.1, + "pfloat32": 14.1, + "pfloat64": 15.1, + "string": "", + "pstring": "16", + "map": null, + "mapp": null, + "pmap": { + "17": { + "tag": "tag17" + }, + "18": { + "tag": "tag18" + } + }, + "pmapp": { + "19": { + "tag": "tag19" + }, + "20": null + }, + "emptymap": null, + "nilmap": null, + "slice": [], + "slicep": [], + "pslice": [ + { + "tag": "tag20" + }, + { + "tag": "tag21" + } + ], + "pslicep": [ + { + "tag": "tag22" + }, + null, + { + "tag": "tag23" + } + ], + "emptyslice": [], + "nilslice": [], + "stringslice": [], + "byteslice": [], + "small": { + "tag": "" + }, + "psmall": null, + "ppsmall": { + "tag": "tag31" + }, + "interface": null, + "pinterface": 5.2 +}` + +var pallValueCompact = strings.Map(noSpace, pallValueIndent) |