1 // Copyright 2011 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.
19 type Optionals
struct {
21 So
string `json:"so,omitempty"`
24 Ir
int `json:"omitempty"` // actually named omitempty, not an option
25 Io
int `json:"io,omitempty"`
27 Slr
[]string `json:"slr,random"`
28 Slo
[]string `json:"slo,omitempty"`
30 Mr
map[string]interface{} `json:"mr"`
31 Mo
map[string]interface{} `json:",omitempty"`
33 Fr
float64 `json:"fr"`
34 Fo
float64 `json:"fo,omitempty"`
37 Bo
bool `json:"bo,omitempty"`
40 Uo
uint `json:"uo,omitempty"`
42 Str
struct{} `json:"str"`
43 Sto
struct{} `json:"sto,omitempty"`
46 var optionalsExpected
= `{
58 func TestOmitEmpty(t
*testing
.T
) {
61 o
.Mr
= map[string]interface{}{}
62 o
.Mo
= map[string]interface{}{}
64 got
, err
:= MarshalIndent(&o
, "", " ")
68 if got
:= string(got
); got
!= optionalsExpected
{
69 t
.Errorf(" got: %s\nwant: %s\n", got
, optionalsExpected
)
73 type StringTag
struct {
74 BoolStr
bool `json:",string"`
75 IntStr
int64 `json:",string"`
76 UintptrStr
uintptr `json:",string"`
77 StrStr
string `json:",string"`
80 var stringTagExpected
= `{
87 func TestStringTag(t
*testing
.T
) {
93 got
, err
:= MarshalIndent(&s
, "", " ")
97 if got
:= string(got
); got
!= stringTagExpected
{
98 t
.Fatalf(" got: %s\nwant: %s\n", got
, stringTagExpected
)
101 // Verify that it round-trips.
103 err
= NewDecoder(bytes
.NewReader(got
)).Decode(&s2
)
105 t
.Fatalf("Decode: %v", err
)
107 if !reflect
.DeepEqual(s
, s2
) {
108 t
.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s
, string(got
), s2
)
112 // byte slices are special even if they're renamed types.
113 type renamedByte
byte
114 type renamedByteSlice
[]byte
115 type renamedRenamedByteSlice
[]renamedByte
117 func TestEncodeRenamedByteSlice(t
*testing
.T
) {
118 s
:= renamedByteSlice("abc")
119 result
, err
:= Marshal(s
)
124 if string(result
) != expect
{
125 t
.Errorf(" got %s want %s", result
, expect
)
127 r
:= renamedRenamedByteSlice("abc")
128 result
, err
= Marshal(r
)
132 if string(result
) != expect
{
133 t
.Errorf(" got %s want %s", result
, expect
)
137 var unsupportedValues
= []interface{}{
143 func TestUnsupportedValues(t
*testing
.T
) {
144 for _
, v
:= range unsupportedValues
{
145 if _
, err
:= Marshal(v
); err
!= nil {
146 if _
, ok
:= err
.(*UnsupportedValueError
); !ok
{
147 t
.Errorf("for %v, got %T want UnsupportedValueError", v
, err
)
150 t
.Errorf("for %v, expected error", v
)
155 // Ref has Marshaler and Unmarshaler methods with pointer receiver.
158 func (*Ref
) MarshalJSON() ([]byte, error
) {
159 return []byte(`"ref"`), nil
162 func (r
*Ref
) UnmarshalJSON([]byte) error
{
167 // Val has Marshaler methods with value receiver.
170 func (Val
) MarshalJSON() ([]byte, error
) {
171 return []byte(`"val"`), nil
174 // RefText has Marshaler and Unmarshaler methods with pointer receiver.
177 func (*RefText
) MarshalText() ([]byte, error
) {
178 return []byte(`"ref"`), nil
181 func (r
*RefText
) UnmarshalText([]byte) error
{
186 // ValText has Marshaler methods with value receiver.
189 func (ValText
) MarshalText() ([]byte, error
) {
190 return []byte(`"val"`), nil
193 func TestRefValMarshal(t
*testing
.T
) {
213 const want
= `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
214 b
, err
:= Marshal(&s
)
216 t
.Fatalf("Marshal: %v", err
)
218 if got
:= string(b
); got
!= want
{
219 t
.Errorf("got %q, want %q", got
, want
)
223 // C implements Marshaler and returns unescaped JSON.
226 func (C
) MarshalJSON() ([]byte, error
) {
227 return []byte(`"<&>"`), nil
230 // CText implements Marshaler and returns unescaped text.
233 func (CText
) MarshalText() ([]byte, error
) {
234 return []byte(`"<&>"`), nil
237 func TestMarshalerEscaping(t
*testing
.T
) {
239 want
:= `"\u003c\u0026\u003e"`
242 t
.Fatalf("Marshal(c): %v", err
)
244 if got
:= string(b
); got
!= want
{
245 t
.Errorf("Marshal(c) = %#q, want %#q", got
, want
)
249 want
= `"\"\u003c\u0026\u003e\""`
252 t
.Fatalf("Marshal(ct): %v", err
)
254 if got
:= string(b
); got
!= want
{
255 t
.Errorf("Marshal(ct) = %#q, want %#q", got
, want
)
259 func TestAnonymousFields(t
*testing
.T
) {
261 label
string // Test name
262 makeInput
func() interface{} // Function to create input value
263 want
string // Expected JSON output
265 // Both S1 and S2 have a field named X. From the perspective of S,
266 // it is ambiguous which one X refers to.
267 // This should not serialize either field.
268 label
: "AmbiguousField",
269 makeInput
: func() interface{} {
271 S1
struct{ x
, X
int }
272 S2
struct{ x
, X
int }
278 return S
{S1
{1, 2}, S2
{3, 4}}
282 label
: "DominantField",
283 // Both S1 and S2 have a field named X, but since S has an X field as
284 // well, it takes precedence over S1.X and S2.X.
285 makeInput
: func() interface{} {
287 S1
struct{ x
, X
int }
288 S2
struct{ x
, X
int }
295 return S
{S1
{1, 2}, S2
{3, 4}, 5, 6}
299 // Unexported embedded field of non-struct type should not be serialized.
300 label
: "UnexportedEmbeddedInt",
301 makeInput
: func() interface{} {
310 // Exported embedded field of non-struct type should be serialized.
311 label
: "ExportedEmbeddedInt",
312 makeInput
: func() interface{} {
321 // Unexported embedded field of pointer to non-struct type
322 // should not be serialized.
323 label
: "UnexportedEmbeddedIntPointer",
324 makeInput
: func() interface{} {
335 // Exported embedded field of pointer to non-struct type
336 // should be serialized.
337 label
: "ExportedEmbeddedIntPointer",
338 makeInput
: func() interface{} {
349 // Exported fields of embedded structs should have their
350 // exported fields be serialized regardless of whether the struct types
351 // themselves are exported.
352 label
: "EmbeddedStruct",
353 makeInput
: func() interface{} {
355 s1
struct{ x
, X
int }
356 S2
struct{ y
, Y
int }
362 return S
{s1
{1, 2}, S2
{3, 4}}
364 want
: `{"X":2,"Y":4}`,
366 // Exported fields of pointers to embedded structs should have their
367 // exported fields be serialized regardless of whether the struct types
368 // themselves are exported.
369 label
: "EmbeddedStructPointer",
370 makeInput
: func() interface{} {
372 s1
struct{ x
, X
int }
373 S2
struct{ y
, Y
int }
379 return S
{&s1
{1, 2}, &S2
{3, 4}}
381 want
: `{"X":2,"Y":4}`,
383 // Exported fields on embedded unexported structs at multiple levels
384 // of nesting should still be serialized.
385 label
: "NestedStructAndInts",
386 makeInput
: func() interface{} {
405 return S
{s1
{1, 2, s2
{3, 4}}, 6}
407 want
: `{"MyInt1":1,"MyInt2":3}`,
410 for _
, tt
:= range tests
{
411 t
.Run(tt
.label
, func(t
*testing
.T
) {
412 b
, err
:= Marshal(tt
.makeInput())
414 t
.Fatalf("Marshal() = %v, want nil error", err
)
416 if string(b
) != tt
.want
{
417 t
.Fatalf("Marshal() = %q, want %q", b
, tt
.want
)
436 // Legal Go: We never use the repeated embedded field (S).
443 // Issue 16042. Even if a nil interface value is passed in
444 // as long as it implements MarshalJSON, it should be marshaled.
445 type nilMarshaler
string
447 func (nm
*nilMarshaler
) MarshalJSON() ([]byte, error
) {
449 return Marshal("0zenil0")
451 return Marshal("zenil:" + string(*nm
))
455 func TestNilMarshal(t
*testing
.T
) {
456 testCases
:= []struct {
460 {v
: nil, want
: `null`},
461 {v
: new(float64), want
: `0`},
462 {v
: []interface{}(nil), want
: `null`},
463 {v
: []string(nil), want
: `null`},
464 {v
: map[string]string(nil), want
: `null`},
465 {v
: []byte(nil), want
: `null`},
466 {v
: struct{ M
string }{"gopher"}, want
: `{"M":"gopher"}`},
467 {v
: struct{ M Marshaler
}{}, want
: `{"M":null}`},
468 {v
: struct{ M Marshaler
}{(*nilMarshaler
)(nil)}, want
: `{"M":"0zenil0"}`},
469 {v
: struct{ M
interface{} }{(*nilMarshaler
)(nil)}, want
: `{"M":null}`},
472 for _
, tt
:= range testCases
{
473 out
, err
:= Marshal(tt
.v
)
474 if err
!= nil ||
string(out
) != tt
.want
{
475 t
.Errorf("Marshal(%#v) = %#q, %#v, want %#q, nil", tt
.v
, out
, err
, tt
.want
)
482 func TestEmbeddedBug(t
*testing
.T
) {
489 t
.Fatal("Marshal:", err
)
494 t
.Fatalf("Marshal: got %s want %s", got
, want
)
496 // Now check that the duplicate field, S, does not appear.
502 t
.Fatal("Marshal:", err
)
507 t
.Fatalf("Marshal: got %s want %s", got
, want
)
511 type BugD
struct { // Same as BugA after tagging.
512 XXX
string `json:"S"`
515 // BugD's tagged S field should dominate BugA's.
521 // Test that a field with a tag dominates untagged fields.
522 func TestTaggedFieldDominates(t
*testing
.T
) {
529 t
.Fatal("Marshal:", err
)
531 want
:= `{"S":"BugD"}`
534 t
.Fatalf("Marshal: got %s want %s", got
, want
)
538 // There are no tags here, so S should not appear.
542 BugY
// Contains a tagged S field through BugD; should not dominate.
545 func TestDuplicatedFieldDisappears(t
*testing
.T
) {
556 t
.Fatal("Marshal:", err
)
561 t
.Fatalf("Marshal: got %s want %s", got
, want
)
565 func TestStringBytes(t
*testing
.T
) {
567 // Test that encodeState.stringBytes and encodeState.string use the same encoding.
569 for i
:= '\u0000'; i
<= unicode
.MaxRune
; i
++ {
572 s
:= string(r
) + "\xff\xff\xffhello" // some invalid UTF-8 too
574 for _
, escapeHTML
:= range []bool{true, false} {
576 es
.string(s
, escapeHTML
)
578 esBytes
:= &encodeState
{}
579 esBytes
.stringBytes([]byte(s
), escapeHTML
)
581 enc
:= es
.Buffer
.String()
582 encBytes
:= esBytes
.Buffer
.String()
585 for i
< len(enc
) && i
< len(encBytes
) && enc
[i
] == encBytes
[i
] {
589 encBytes
= encBytes
[i
:]
591 for i
< len(enc
) && i
< len(encBytes
) && enc
[len(enc
)-i
-1] == encBytes
[len(encBytes
)-i
-1] {
594 enc
= enc
[:len(enc
)-i
]
595 encBytes
= encBytes
[:len(encBytes
)-i
]
598 enc
= enc
[:20] + "..."
600 if len(encBytes
) > 20 {
601 encBytes
= encBytes
[:20] + "..."
604 t
.Errorf("with escapeHTML=%t, encodings differ at %#q vs %#q",
605 escapeHTML
, enc
, encBytes
)
610 func TestIssue10281(t
*testing
.T
) {
614 x
:= Foo
{Number(`invalid`)}
616 b
, err
:= Marshal(&x
)
618 t
.Errorf("Marshal(&x) = %#q; want error", b
)
622 func TestHTMLEscape(t
*testing
.T
) {
623 var b
, want bytes
.Buffer
624 m
:= `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
625 want
.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
626 HTMLEscape(&b
, []byte(m
))
627 if !bytes
.Equal(b
.Bytes(), want
.Bytes()) {
628 t
.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b
.Bytes(), want
.Bytes())
632 // golang.org/issue/8582
633 func TestEncodePointerString(t
*testing
.T
) {
634 type stringPointer
struct {
635 N
*int64 `json:"n,string"`
638 b
, err
:= Marshal(stringPointer
{N
: &n
})
640 t
.Fatalf("Marshal: %v", err
)
642 if got
, want
:= string(b
), `{"n":"42"}`; got
!= want
{
643 t
.Errorf("Marshal = %s, want %s", got
, want
)
645 var back stringPointer
646 err
= Unmarshal(b
, &back
)
648 t
.Fatalf("Unmarshal: %v", err
)
651 t
.Fatalf("Unmarshaled nil N field")
654 t
.Fatalf("*N = %d; want 42", *back
.N
)
658 var encodeStringTests
= []struct {
662 {"\x00", `"\u0000"`},
663 {"\x01", `"\u0001"`},
664 {"\x02", `"\u0002"`},
665 {"\x03", `"\u0003"`},
666 {"\x04", `"\u0004"`},
667 {"\x05", `"\u0005"`},
668 {"\x06", `"\u0006"`},
669 {"\x07", `"\u0007"`},
670 {"\x08", `"\u0008"`},
673 {"\x0b", `"\u000b"`},
674 {"\x0c", `"\u000c"`},
676 {"\x0e", `"\u000e"`},
677 {"\x0f", `"\u000f"`},
678 {"\x10", `"\u0010"`},
679 {"\x11", `"\u0011"`},
680 {"\x12", `"\u0012"`},
681 {"\x13", `"\u0013"`},
682 {"\x14", `"\u0014"`},
683 {"\x15", `"\u0015"`},
684 {"\x16", `"\u0016"`},
685 {"\x17", `"\u0017"`},
686 {"\x18", `"\u0018"`},
687 {"\x19", `"\u0019"`},
688 {"\x1a", `"\u001a"`},
689 {"\x1b", `"\u001b"`},
690 {"\x1c", `"\u001c"`},
691 {"\x1d", `"\u001d"`},
692 {"\x1e", `"\u001e"`},
693 {"\x1f", `"\u001f"`},
696 func TestEncodeString(t
*testing
.T
) {
697 for _
, tt
:= range encodeStringTests
{
698 b
, err
:= Marshal(tt
.in
)
700 t
.Errorf("Marshal(%q): %v", tt
.in
, err
)
705 t
.Errorf("Marshal(%q) = %#q, want %#q", tt
.in
, out
, tt
.out
)
712 func (b jsonbyte
) MarshalJSON() ([]byte, error
) { return tenc(`{"JB":%d}`, b
) }
716 func (b textbyte
) MarshalText() ([]byte, error
) { return tenc(`TB:%d`, b
) }
720 func (i jsonint
) MarshalJSON() ([]byte, error
) { return tenc(`{"JI":%d}`, i
) }
724 func (i textint
) MarshalText() ([]byte, error
) { return tenc(`TI:%d`, i
) }
726 func tenc(format
string, a
...interface{}) ([]byte, error
) {
728 fmt
.Fprintf(&buf
, format
, a
...)
729 return buf
.Bytes(), nil
733 func TestEncodeBytekind(t
*testing
.T
) {
734 testdata
:= []struct {
739 {jsonbyte(7), `{"JB":7}`},
740 {textbyte(4), `"TB:4"`},
741 {jsonint(5), `{"JI":5}`},
742 {textint(1), `"TI:1"`},
743 {[]byte{0, 1}, `"AAE="`},
744 {[]jsonbyte
{0, 1}, `[{"JB":0},{"JB":1}]`},
745 {[][]jsonbyte
{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`},
746 {[]textbyte
{2, 3}, `["TB:2","TB:3"]`},
747 {[]jsonint
{5, 4}, `[{"JI":5},{"JI":4}]`},
748 {[]textint
{9, 3}, `["TI:9","TI:3"]`},
749 {[]int{9, 3}, `[9,3]`},
751 for _
, d
:= range testdata
{
752 js
, err
:= Marshal(d
.data
)
757 got
, want
:= string(js
), d
.want
759 t
.Errorf("got %s, want %s", got
, want
)
764 func TestTextMarshalerMapKeysAreSorted(t
*testing
.T
) {
765 b
, err
:= Marshal(map[unmarshalerText
]int{
772 t
.Fatalf("Failed to Marshal text.Marshaler: %v", err
)
774 const want
= `{"a:z":3,"x:y":1,"y:x":2,"z:a":4}`
775 if string(b
) != want
{
776 t
.Errorf("Marshal map with text.Marshaler keys: got %#q, want %#q", b
, want
)
780 var re
= regexp
.MustCompile
782 // syntactic checks on form of marshaled floating point numbers.
783 var badFloatREs
= []*regexp
.Regexp
{
784 re(`p`), // no binary exponential notation
785 re(`^\+`), // no leading + sign
786 re(`^-?0[^.]`), // no unnecessary leading zeros
787 re(`^-?\.`), // leading zero required before decimal point
788 re(`\.(e|$)`), // no trailing decimal
789 re(`\.[0-9]+0(e|$)`), // no trailing zero in fraction
790 re(`^-?(0|[0-9]{2,})\..*e`), // exponential notation must have normalized mantissa
791 re(`e[0-9]`), // positive exponent must be signed
792 re(`e[+-]0`), // exponent must not have leading zeros
793 re(`e-[1-6]$`), // not tiny enough for exponential notation
794 re(`e+(.|1.|20)$`), // not big enough for exponential notation
795 re(`^-?0\.0000000`), // too tiny, should use exponential notation
796 re(`^-?[0-9]{22}`), // too big, should use exponential notation
797 re(`[1-9][0-9]{16}[1-9]`), // too many significant digits in integer
798 re(`[1-9][0-9.]{17}[1-9]`), // too many significant digits in decimal
799 // below here for float32 only
800 re(`[1-9][0-9]{8}[1-9]`), // too many significant digits in integer
801 re(`[1-9][0-9.]{9}[1-9]`), // too many significant digits in decimal
804 func TestMarshalFloat(t
*testing
.T
) {
807 test
:= func(f
float64, bits
int) {
810 f
= float64(float32(f
)) // round
813 bout
, err
:= Marshal(vf
)
815 t
.Errorf("Marshal(%T(%g)): %v", vf
, vf
, err
)
821 // result must convert back to the same float
822 g
, err
:= strconv
.ParseFloat(out
, bits
)
824 t
.Errorf("Marshal(%T(%g)) = %q, cannot parse back: %v", vf
, vf
, out
, err
)
828 if f
!= g || fmt
.Sprint(f
) != fmt
.Sprint(g
) { // fmt.Sprint handles ±0
829 t
.Errorf("Marshal(%T(%g)) = %q (is %g, not %g)", vf
, vf
, out
, float32(g
), vf
)
836 bad
= bad
[:len(bad
)-2]
838 for _
, re
:= range bad
{
839 if re
.MatchString(out
) {
840 t
.Errorf("Marshal(%T(%g)) = %q, must not match /%s/", vf
, vf
, out
, re
)
848 bigger
= math
.Inf(+1)
849 smaller
= math
.Inf(-1)
852 var digits
= "1.2345678901234567890123"
853 for i
:= len(digits
); i
>= 2; i
-- {
854 for exp
:= -30; exp
<= 30; exp
++ {
855 for _
, sign
:= range "+-" {
856 for bits
:= 32; bits
<= 64; bits
+= 32 {
857 s
:= fmt
.Sprintf("%c%se%d", sign
, digits
[:i
], exp
)
858 f
, err
:= strconv
.ParseFloat(s
, bits
)
862 next
:= math
.Nextafter
864 next
= func(g
, h
float64) float64 {
865 return float64(math
.Nextafter32(float32(g
), float32(h
)))
869 test(next(f
, bigger
), bits
)
870 test(next(f
, smaller
), bits
)
872 t
.Fatalf("stopping test early")
879 test(math
.Copysign(0, -1), 64)
881 test(math
.Copysign(0, -1), 32)
884 func TestMarshalRawMessageValue(t
*testing
.T
) {
887 M RawMessage
`json:",omitempty"`
890 M
*RawMessage
`json:",omitempty"`
895 rawNil
= RawMessage(nil)
896 rawEmpty
= RawMessage([]byte{})
897 rawText
= RawMessage([]byte(`"foo"`))
905 // Test with nil RawMessage.
906 {rawNil
, "null", true},
907 {&rawNil
, "null", true},
908 {[]interface{}{rawNil
}, "[null]", true},
909 {&[]interface{}{rawNil
}, "[null]", true},
910 {[]interface{}{&rawNil
}, "[null]", true},
911 {&[]interface{}{&rawNil
}, "[null]", true},
912 {struct{ M RawMessage
}{rawNil
}, `{"M":null}`, true},
913 {&struct{ M RawMessage
}{rawNil
}, `{"M":null}`, true},
914 {struct{ M
*RawMessage
}{&rawNil
}, `{"M":null}`, true},
915 {&struct{ M
*RawMessage
}{&rawNil
}, `{"M":null}`, true},
916 {map[string]interface{}{"M": rawNil
}, `{"M":null}`, true},
917 {&map[string]interface{}{"M": rawNil
}, `{"M":null}`, true},
918 {map[string]interface{}{"M": &rawNil
}, `{"M":null}`, true},
919 {&map[string]interface{}{"M": &rawNil
}, `{"M":null}`, true},
920 {T1
{rawNil
}, "{}", true},
921 {T2
{&rawNil
}, `{"M":null}`, true},
922 {&T1
{rawNil
}, "{}", true},
923 {&T2
{&rawNil
}, `{"M":null}`, true},
925 // Test with empty, but non-nil, RawMessage.
926 {rawEmpty
, "", false},
927 {&rawEmpty
, "", false},
928 {[]interface{}{rawEmpty
}, "", false},
929 {&[]interface{}{rawEmpty
}, "", false},
930 {[]interface{}{&rawEmpty
}, "", false},
931 {&[]interface{}{&rawEmpty
}, "", false},
932 {struct{ X RawMessage
}{rawEmpty
}, "", false},
933 {&struct{ X RawMessage
}{rawEmpty
}, "", false},
934 {struct{ X
*RawMessage
}{&rawEmpty
}, "", false},
935 {&struct{ X
*RawMessage
}{&rawEmpty
}, "", false},
936 {map[string]interface{}{"nil": rawEmpty
}, "", false},
937 {&map[string]interface{}{"nil": rawEmpty
}, "", false},
938 {map[string]interface{}{"nil": &rawEmpty
}, "", false},
939 {&map[string]interface{}{"nil": &rawEmpty
}, "", false},
940 {T1
{rawEmpty
}, "{}", true},
941 {T2
{&rawEmpty
}, "", false},
942 {&T1
{rawEmpty
}, "{}", true},
943 {&T2
{&rawEmpty
}, "", false},
945 // Test with RawMessage with some text.
947 // The tests below marked with Issue6458 used to generate "ImZvbyI=" instead "foo".
948 // This behavior was intentionally changed in Go 1.8.
949 // See https://golang.org/issues/14493#issuecomment-255857318
950 {rawText
, `"foo"`, true}, // Issue6458
951 {&rawText
, `"foo"`, true},
952 {[]interface{}{rawText
}, `["foo"]`, true}, // Issue6458
953 {&[]interface{}{rawText
}, `["foo"]`, true}, // Issue6458
954 {[]interface{}{&rawText
}, `["foo"]`, true},
955 {&[]interface{}{&rawText
}, `["foo"]`, true},
956 {struct{ M RawMessage
}{rawText
}, `{"M":"foo"}`, true}, // Issue6458
957 {&struct{ M RawMessage
}{rawText
}, `{"M":"foo"}`, true},
958 {struct{ M
*RawMessage
}{&rawText
}, `{"M":"foo"}`, true},
959 {&struct{ M
*RawMessage
}{&rawText
}, `{"M":"foo"}`, true},
960 {map[string]interface{}{"M": rawText
}, `{"M":"foo"}`, true}, // Issue6458
961 {&map[string]interface{}{"M": rawText
}, `{"M":"foo"}`, true}, // Issue6458
962 {map[string]interface{}{"M": &rawText
}, `{"M":"foo"}`, true},
963 {&map[string]interface{}{"M": &rawText
}, `{"M":"foo"}`, true},
964 {T1
{rawText
}, `{"M":"foo"}`, true}, // Issue6458
965 {T2
{&rawText
}, `{"M":"foo"}`, true},
966 {&T1
{rawText
}, `{"M":"foo"}`, true},
967 {&T2
{&rawText
}, `{"M":"foo"}`, true},
970 for i
, tt
:= range tests
{
971 b
, err
:= Marshal(tt
.in
)
972 if ok
:= (err
== nil); ok
!= tt
.ok
{
974 t
.Errorf("test %d, unexpected failure: %v", i
, err
)
976 t
.Errorf("test %d, unexpected success", i
)
979 if got
:= string(b
); got
!= tt
.want
{
980 t
.Errorf("test %d, Marshal(%#v) = %q, want %q", i
, tt
.in
, got
, tt
.want
)