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.go107
1 files changed, 85 insertions, 22 deletions
diff --git a/src/pkg/json/decode_test.go b/src/pkg/json/decode_test.go
index e10b2c56e..68cdea051 100644
--- a/src/pkg/json/decode_test.go
+++ b/src/pkg/json/decode_test.go
@@ -17,6 +17,30 @@ type T struct {
Y int
}
+type tx struct {
+ x int
+}
+
+var txType = reflect.Typeof((*tx)(nil)).(*reflect.PtrType).Elem().(*reflect.StructType)
+
+// A type that can unmarshal itself.
+
+type unmarshaler struct {
+ T bool
+}
+
+func (u *unmarshaler) UnmarshalJSON(b []byte) os.Error {
+ *u = unmarshaler{true} // All we need to see that UnmarshalJson is called.
+ return nil
+}
+
+var (
+ um0, um1 unmarshaler // target2 of unmarshaling
+ ump = &um1
+ umtrue = unmarshaler{true}
+)
+
+
type unmarshalTest struct {
in string
ptr interface{}
@@ -26,26 +50,34 @@ type unmarshalTest struct {
var unmarshalTests = []unmarshalTest{
// basic types
- unmarshalTest{`true`, new(bool), true, nil},
- unmarshalTest{`1`, new(int), 1, nil},
- unmarshalTest{`1.2`, new(float), 1.2, nil},
- unmarshalTest{`-5`, new(int16), int16(-5), nil},
- unmarshalTest{`"a\u1234"`, new(string), "a\u1234", nil},
- unmarshalTest{`"http:\/\/"`, new(string), "http://", nil},
- unmarshalTest{`"g-clef: \uD834\uDD1E"`, new(string), "g-clef: \U0001D11E", nil},
- unmarshalTest{`"invalid: \uD834x\uDD1E"`, new(string), "invalid: \uFFFDx\uFFFD", nil},
- unmarshalTest{"null", new(interface{}), nil, nil},
- unmarshalTest{`{"X": [1,2,3], "Y": 4}`, new(T), T{Y: 4}, &UnmarshalTypeError{"array", reflect.Typeof("")}},
+ {`true`, new(bool), true, nil},
+ {`1`, new(int), 1, nil},
+ {`1.2`, new(float), 1.2, nil},
+ {`-5`, new(int16), int16(-5), nil},
+ {`"a\u1234"`, new(string), "a\u1234", nil},
+ {`"http:\/\/"`, new(string), "http://", nil},
+ {`"g-clef: \uD834\uDD1E"`, new(string), "g-clef: \U0001D11E", nil},
+ {`"invalid: \uD834x\uDD1E"`, new(string), "invalid: \uFFFDx\uFFFD", nil},
+ {"null", new(interface{}), nil, nil},
+ {`{"X": [1,2,3], "Y": 4}`, new(T), T{Y: 4}, &UnmarshalTypeError{"array", reflect.Typeof("")}},
+ {`{"x": 1}`, new(tx), tx{}, &UnmarshalFieldError{"x", txType, txType.Field(0)}},
+
+ // syntax errors
+ {`{"X": "foo", "Y"}`, nil, nil, SyntaxError("invalid character '}' after object key")},
// composite tests
- unmarshalTest{allValueIndent, new(All), allValue, nil},
- unmarshalTest{allValueCompact, new(All), allValue, nil},
- unmarshalTest{allValueIndent, new(*All), &allValue, nil},
- unmarshalTest{allValueCompact, new(*All), &allValue, nil},
- unmarshalTest{pallValueIndent, new(All), pallValue, nil},
- unmarshalTest{pallValueCompact, new(All), pallValue, nil},
- unmarshalTest{pallValueIndent, new(*All), &pallValue, nil},
- unmarshalTest{pallValueCompact, new(*All), &pallValue, nil},
+ {allValueIndent, new(All), allValue, nil},
+ {allValueCompact, new(All), allValue, nil},
+ {allValueIndent, new(*All), &allValue, nil},
+ {allValueCompact, new(*All), &allValue, nil},
+ {pallValueIndent, new(All), pallValue, nil},
+ {pallValueCompact, new(All), pallValue, nil},
+ {pallValueIndent, new(*All), &pallValue, nil},
+ {pallValueCompact, new(*All), &pallValue, nil},
+
+ // unmarshal interface test
+ {`{"T":false}`, &um0, umtrue, nil}, // use "false" so test will fail if custom unmarshaler is not called
+ {`{"T":false}`, &ump, &umtrue, nil},
}
func TestMarshal(t *testing.T) {
@@ -70,12 +102,31 @@ func TestMarshal(t *testing.T) {
}
}
+func TestMarshalBadUTF8(t *testing.T) {
+ s := "hello\xffworld"
+ b, err := Marshal(s)
+ if err == nil {
+ t.Fatal("Marshal bad UTF8: no error")
+ }
+ if len(b) != 0 {
+ t.Fatal("Marshal returned data")
+ }
+ if _, ok := err.(*InvalidUTF8Error); !ok {
+ t.Fatalf("Marshal did not return InvalidUTF8Error: %T %v", err, err)
+ }
+}
+
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)
+ if !reflect.DeepEqual(err, tt.err) {
+ t.Errorf("#%d: checkValid: %v", i, err)
+ continue
+ }
+ }
+ if tt.ptr == nil {
continue
}
// v = new(right-type)
@@ -139,6 +190,16 @@ func TestUnmarshalPtrPtr(t *testing.T) {
}
}
+func TestHTMLEscape(t *testing.T) {
+ b, err := MarshalForHTML("foobarbaz<>&quux")
+ if err != nil {
+ t.Fatalf("MarshalForHTML error: %v", err)
+ }
+ if !bytes.Equal(b, []byte(`"foobarbaz\u003c\u003e\u0026quux"`)) {
+ t.Fatalf("Unexpected encoding of \"<>&\": %s", b)
+ }
+}
+
func noSpace(c int) int {
if isSpace(c) {
return -1
@@ -209,6 +270,8 @@ type All struct {
Interface interface{}
PInterface *interface{}
+
+ unexported int
}
type Small struct {
@@ -234,15 +297,15 @@ var allValue = All{
Foo: "foo",
String: "16",
Map: map[string]Small{
- "17": Small{Tag: "tag17"},
- "18": Small{Tag: "tag18"},
+ "17": {Tag: "tag17"},
+ "18": {Tag: "tag18"},
},
MapP: map[string]*Small{
"19": &Small{Tag: "tag19"},
"20": nil,
},
EmptyMap: map[string]Small{},
- Slice: []Small{Small{Tag: "tag20"}, Small{Tag: "tag21"}},
+ Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}},
SliceP: []*Small{&Small{Tag: "tag22"}, nil, &Small{Tag: "tag23"}},
EmptySlice: []Small{},
StringSlice: []string{"str24", "str25", "str26"},