summaryrefslogtreecommitdiff
path: root/libgo/go/encoding/json/encode_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/encoding/json/encode_test.go')
-rw-r--r--libgo/go/encoding/json/encode_test.go113
1 files changed, 105 insertions, 8 deletions
diff --git a/libgo/go/encoding/json/encode_test.go b/libgo/go/encoding/json/encode_test.go
index bdf2a9f0792..5110c7de9b1 100644
--- a/libgo/go/encoding/json/encode_test.go
+++ b/libgo/go/encoding/json/encode_test.go
@@ -6,6 +6,7 @@ package json
import (
"bytes"
+ "encoding"
"fmt"
"log"
"math"
@@ -75,13 +76,15 @@ type StringTag struct {
IntStr int64 `json:",string"`
UintptrStr uintptr `json:",string"`
StrStr string `json:",string"`
+ NumberStr Number `json:",string"`
}
var stringTagExpected = `{
"BoolStr": "true",
"IntStr": "42",
"UintptrStr": "44",
- "StrStr": "\"xzbit\""
+ "StrStr": "\"xzbit\"",
+ "NumberStr": "46"
}`
func TestStringTag(t *testing.T) {
@@ -90,6 +93,7 @@ func TestStringTag(t *testing.T) {
s.IntStr = 42
s.UintptrStr = 44
s.StrStr = "xzbit"
+ s.NumberStr = "46"
got, err := MarshalIndent(&s, "", " ")
if err != nil {
t.Fatal(err)
@@ -134,10 +138,45 @@ func TestEncodeRenamedByteSlice(t *testing.T) {
}
}
+type SamePointerNoCycle struct {
+ Ptr1, Ptr2 *SamePointerNoCycle
+}
+
+var samePointerNoCycle = &SamePointerNoCycle{}
+
+type PointerCycle struct {
+ Ptr *PointerCycle
+}
+
+var pointerCycle = &PointerCycle{}
+
+type PointerCycleIndirect struct {
+ Ptrs []interface{}
+}
+
+var pointerCycleIndirect = &PointerCycleIndirect{}
+
+func init() {
+ ptr := &SamePointerNoCycle{}
+ samePointerNoCycle.Ptr1 = ptr
+ samePointerNoCycle.Ptr2 = ptr
+
+ pointerCycle.Ptr = pointerCycle
+ pointerCycleIndirect.Ptrs = []interface{}{pointerCycleIndirect}
+}
+
+func TestSamePointerNoCycle(t *testing.T) {
+ if _, err := Marshal(samePointerNoCycle); err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+}
+
var unsupportedValues = []interface{}{
math.NaN(),
math.Inf(-1),
math.Inf(1),
+ pointerCycle,
+ pointerCycleIndirect,
}
func TestUnsupportedValues(t *testing.T) {
@@ -453,18 +492,31 @@ type BugX struct {
BugB
}
-// Issue 16042. Even if a nil interface value is passed in
-// as long as it implements MarshalJSON, it should be marshaled.
-type nilMarshaler string
+// golang.org/issue/16042.
+// Even if a nil interface value is passed in, as long as
+// it implements Marshaler, it should be marshaled.
+type nilJSONMarshaler string
-func (nm *nilMarshaler) MarshalJSON() ([]byte, error) {
+func (nm *nilJSONMarshaler) MarshalJSON() ([]byte, error) {
if nm == nil {
return Marshal("0zenil0")
}
return Marshal("zenil:" + string(*nm))
}
-// Issue 16042.
+// golang.org/issue/34235.
+// Even if a nil interface value is passed in, as long as
+// it implements encoding.TextMarshaler, it should be marshaled.
+type nilTextMarshaler string
+
+func (nm *nilTextMarshaler) MarshalText() ([]byte, error) {
+ if nm == nil {
+ return []byte("0zenil0"), nil
+ }
+ return []byte("zenil:" + string(*nm)), nil
+}
+
+// See golang.org/issue/16042 and golang.org/issue/34235.
func TestNilMarshal(t *testing.T) {
testCases := []struct {
v interface{}
@@ -478,8 +530,11 @@ func TestNilMarshal(t *testing.T) {
{v: []byte(nil), want: `null`},
{v: struct{ M string }{"gopher"}, want: `{"M":"gopher"}`},
{v: struct{ M Marshaler }{}, want: `{"M":null}`},
- {v: struct{ M Marshaler }{(*nilMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
- {v: struct{ M interface{} }{(*nilMarshaler)(nil)}, want: `{"M":null}`},
+ {v: struct{ M Marshaler }{(*nilJSONMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
+ {v: struct{ M interface{} }{(*nilJSONMarshaler)(nil)}, want: `{"M":null}`},
+ {v: struct{ M encoding.TextMarshaler }{}, want: `{"M":null}`},
+ {v: struct{ M encoding.TextMarshaler }{(*nilTextMarshaler)(nil)}, want: `{"M":"0zenil0"}`},
+ {v: struct{ M interface{} }{(*nilTextMarshaler)(nil)}, want: `{"M":null}`},
}
for _, tt := range testCases {
@@ -793,6 +848,21 @@ func TestTextMarshalerMapKeysAreSorted(t *testing.T) {
}
}
+// https://golang.org/issue/33675
+func TestNilMarshalerTextMapKey(t *testing.T) {
+ b, err := Marshal(map[*unmarshalerText]int{
+ (*unmarshalerText)(nil): 1,
+ {"A", "B"}: 2,
+ })
+ if err != nil {
+ t.Fatalf("Failed to Marshal *text.Marshaler: %v", err)
+ }
+ const want = `{"":1,"A:B":2}`
+ if string(b) != want {
+ t.Errorf("Marshal map with *text.Marshaler keys: got %#q, want %#q", b, want)
+ }
+}
+
var re = regexp.MustCompile
// syntactic checks on form of marshaled floating point numbers.
@@ -1029,3 +1099,30 @@ func TestMarshalUncommonFieldNames(t *testing.T) {
t.Fatalf("Marshal: got %s want %s", got, want)
}
}
+
+func TestMarshalerError(t *testing.T) {
+ s := "test variable"
+ st := reflect.TypeOf(s)
+ errText := "json: test error"
+
+ tests := []struct {
+ err *MarshalerError
+ want string
+ }{
+ {
+ &MarshalerError{st, fmt.Errorf(errText), ""},
+ "json: error calling MarshalJSON for type " + st.String() + ": " + errText,
+ },
+ {
+ &MarshalerError{st, fmt.Errorf(errText), "TestMarshalerError"},
+ "json: error calling TestMarshalerError for type " + st.String() + ": " + errText,
+ },
+ }
+
+ for i, tt := range tests {
+ got := tt.err.Error()
+ if got != tt.want {
+ t.Errorf("MarshalerError test %d, got: %s, want: %s", i, got, tt.want)
+ }
+ }
+}