summaryrefslogtreecommitdiff
path: root/src/pkg/json/decode_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/json/decode_test.go')
-rw-r--r--src/pkg/json/decode_test.go488
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)