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.
20 type Optionals
struct {
22 So
string `json:"so,omitempty"`
25 Ir
int `json:"omitempty"` // actually named omitempty, not an option
26 Io
int `json:"io,omitempty"`
28 Slr
[]string `json:"slr,random"`
29 Slo
[]string `json:"slo,omitempty"`
31 Mr
map[string]any
`json:"mr"`
32 Mo
map[string]any
`json:",omitempty"`
34 Fr
float64 `json:"fr"`
35 Fo
float64 `json:"fo,omitempty"`
38 Bo
bool `json:"bo,omitempty"`
41 Uo
uint `json:"uo,omitempty"`
43 Str
struct{} `json:"str"`
44 Sto
struct{} `json:"sto,omitempty"`
47 var optionalsExpected
= `{
59 func TestOmitEmpty(t
*testing
.T
) {
62 o
.Mr
= map[string]any
{}
63 o
.Mo
= map[string]any
{}
65 got
, err
:= MarshalIndent(&o
, "", " ")
69 if got
:= string(got
); got
!= optionalsExpected
{
70 t
.Errorf(" got: %s\nwant: %s\n", got
, optionalsExpected
)
74 type StringTag
struct {
75 BoolStr
bool `json:",string"`
76 IntStr
int64 `json:",string"`
77 UintptrStr
uintptr `json:",string"`
78 StrStr
string `json:",string"`
79 NumberStr Number
`json:",string"`
82 func TestRoundtripStringTag(t
*testing
.T
) {
86 want
string // empty to just test that we roundtrip
101 "StrStr": "\"xzbit\"",
106 // See golang.org/issues/38173.
107 name
: "StringDoubleEscapes",
109 StrStr
: "\b\f\n\r\t\"\\",
110 NumberStr
: "0", // just to satisfy the roundtrip
116 "StrStr": "\"\\u0008\\u000c\\n\\r\\t\\\"\\\\\"",
121 for _
, test
:= range tests
{
122 t
.Run(test
.name
, func(t
*testing
.T
) {
123 // Indent with a tab prefix to make the multi-line string
124 // literals in the table nicer to read.
125 got
, err
:= MarshalIndent(&test
.in
, "\t\t\t", "\t")
129 if got
:= string(got
); got
!= test
.want
{
130 t
.Fatalf(" got: %s\nwant: %s\n", got
, test
.want
)
133 // Verify that it round-trips.
135 if err
:= Unmarshal(got
, &s2
); err
!= nil {
136 t
.Fatalf("Decode: %v", err
)
138 if !reflect
.DeepEqual(test
.in
, s2
) {
139 t
.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", test
.in
, string(got
), s2
)
145 // byte slices are special even if they're renamed types.
146 type renamedByte
byte
147 type renamedByteSlice
[]byte
148 type renamedRenamedByteSlice
[]renamedByte
150 func TestEncodeRenamedByteSlice(t
*testing
.T
) {
151 s
:= renamedByteSlice("abc")
152 result
, err
:= Marshal(s
)
157 if string(result
) != expect
{
158 t
.Errorf(" got %s want %s", result
, expect
)
160 r
:= renamedRenamedByteSlice("abc")
161 result
, err
= Marshal(r
)
165 if string(result
) != expect
{
166 t
.Errorf(" got %s want %s", result
, expect
)
170 type SamePointerNoCycle
struct {
171 Ptr1
, Ptr2
*SamePointerNoCycle
174 var samePointerNoCycle
= &SamePointerNoCycle
{}
176 type PointerCycle
struct {
180 var pointerCycle
= &PointerCycle
{}
182 type PointerCycleIndirect
struct {
186 type RecursiveSlice
[]RecursiveSlice
189 pointerCycleIndirect
= &PointerCycleIndirect
{}
190 mapCycle
= make(map[string]any
)
191 sliceCycle
= []any
{nil}
192 sliceNoCycle
= []any
{nil, nil}
193 recursiveSliceCycle
= []RecursiveSlice
{nil}
197 ptr
:= &SamePointerNoCycle
{}
198 samePointerNoCycle
.Ptr1
= ptr
199 samePointerNoCycle
.Ptr2
= ptr
201 pointerCycle
.Ptr
= pointerCycle
202 pointerCycleIndirect
.Ptrs
= []any
{pointerCycleIndirect
}
204 mapCycle
["x"] = mapCycle
205 sliceCycle
[0] = sliceCycle
206 sliceNoCycle
[1] = sliceNoCycle
[:1]
207 for i
:= startDetectingCyclesAfter
; i
> 0; i
-- {
208 sliceNoCycle
= []any
{sliceNoCycle
}
210 recursiveSliceCycle
[0] = recursiveSliceCycle
213 func TestSamePointerNoCycle(t
*testing
.T
) {
214 if _
, err
:= Marshal(samePointerNoCycle
); err
!= nil {
215 t
.Fatalf("unexpected error: %v", err
)
219 func TestSliceNoCycle(t
*testing
.T
) {
220 if _
, err
:= Marshal(sliceNoCycle
); err
!= nil {
221 t
.Fatalf("unexpected error: %v", err
)
225 var unsupportedValues
= []any
{
230 pointerCycleIndirect
,
236 func TestUnsupportedValues(t
*testing
.T
) {
237 for _
, v
:= range unsupportedValues
{
238 if _
, err
:= Marshal(v
); err
!= nil {
239 if _
, ok
:= err
.(*UnsupportedValueError
); !ok
{
240 t
.Errorf("for %v, got %T want UnsupportedValueError", v
, err
)
243 t
.Errorf("for %v, expected error", v
)
249 func TestMarshalTextFloatMap(t
*testing
.T
) {
250 m
:= map[textfloat
]string{
251 textfloat(math
.NaN()): "1",
252 textfloat(math
.NaN()): "1",
254 got
, err
:= Marshal(m
)
256 t
.Errorf("Marshal() error: %v", err
)
258 want
:= `{"TF:NaN":"1","TF:NaN":"1"}`
259 if string(got
) != want
{
260 t
.Errorf("Marshal() = %s, want %s", got
, want
)
264 // Ref has Marshaler and Unmarshaler methods with pointer receiver.
267 func (*Ref
) MarshalJSON() ([]byte, error
) {
268 return []byte(`"ref"`), nil
271 func (r
*Ref
) UnmarshalJSON([]byte) error
{
276 // Val has Marshaler methods with value receiver.
279 func (Val
) MarshalJSON() ([]byte, error
) {
280 return []byte(`"val"`), nil
283 // RefText has Marshaler and Unmarshaler methods with pointer receiver.
286 func (*RefText
) MarshalText() ([]byte, error
) {
287 return []byte(`"ref"`), nil
290 func (r
*RefText
) UnmarshalText([]byte) error
{
295 // ValText has Marshaler methods with value receiver.
298 func (ValText
) MarshalText() ([]byte, error
) {
299 return []byte(`"val"`), nil
302 func TestRefValMarshal(t
*testing
.T
) {
322 const want
= `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
323 b
, err
:= Marshal(&s
)
325 t
.Fatalf("Marshal: %v", err
)
327 if got
:= string(b
); got
!= want
{
328 t
.Errorf("got %q, want %q", got
, want
)
332 // C implements Marshaler and returns unescaped JSON.
335 func (C
) MarshalJSON() ([]byte, error
) {
336 return []byte(`"<&>"`), nil
339 // CText implements Marshaler and returns unescaped text.
342 func (CText
) MarshalText() ([]byte, error
) {
343 return []byte(`"<&>"`), nil
346 func TestMarshalerEscaping(t
*testing
.T
) {
348 want
:= `"\u003c\u0026\u003e"`
351 t
.Fatalf("Marshal(c): %v", err
)
353 if got
:= string(b
); got
!= want
{
354 t
.Errorf("Marshal(c) = %#q, want %#q", got
, want
)
358 want
= `"\"\u003c\u0026\u003e\""`
361 t
.Fatalf("Marshal(ct): %v", err
)
363 if got
:= string(b
); got
!= want
{
364 t
.Errorf("Marshal(ct) = %#q, want %#q", got
, want
)
368 func TestAnonymousFields(t
*testing
.T
) {
370 label
string // Test name
371 makeInput
func() any
// Function to create input value
372 want
string // Expected JSON output
374 // Both S1 and S2 have a field named X. From the perspective of S,
375 // it is ambiguous which one X refers to.
376 // This should not serialize either field.
377 label
: "AmbiguousField",
378 makeInput
: func() any
{
380 S1
struct{ x
, X
int }
381 S2
struct{ x
, X
int }
387 return S
{S1
{1, 2}, S2
{3, 4}}
391 label
: "DominantField",
392 // Both S1 and S2 have a field named X, but since S has an X field as
393 // well, it takes precedence over S1.X and S2.X.
394 makeInput
: func() any
{
396 S1
struct{ x
, X
int }
397 S2
struct{ x
, X
int }
404 return S
{S1
{1, 2}, S2
{3, 4}, 5, 6}
408 // Unexported embedded field of non-struct type should not be serialized.
409 label
: "UnexportedEmbeddedInt",
410 makeInput
: func() any
{
419 // Exported embedded field of non-struct type should be serialized.
420 label
: "ExportedEmbeddedInt",
421 makeInput
: func() any
{
430 // Unexported embedded field of pointer to non-struct type
431 // should not be serialized.
432 label
: "UnexportedEmbeddedIntPointer",
433 makeInput
: func() any
{
444 // Exported embedded field of pointer to non-struct type
445 // should be serialized.
446 label
: "ExportedEmbeddedIntPointer",
447 makeInput
: func() any
{
458 // Exported fields of embedded structs should have their
459 // exported fields be serialized regardless of whether the struct types
460 // themselves are exported.
461 label
: "EmbeddedStruct",
462 makeInput
: func() any
{
464 s1
struct{ x
, X
int }
465 S2
struct{ y
, Y
int }
471 return S
{s1
{1, 2}, S2
{3, 4}}
473 want
: `{"X":2,"Y":4}`,
475 // Exported fields of pointers to embedded structs should have their
476 // exported fields be serialized regardless of whether the struct types
477 // themselves are exported.
478 label
: "EmbeddedStructPointer",
479 makeInput
: func() any
{
481 s1
struct{ x
, X
int }
482 S2
struct{ y
, Y
int }
488 return S
{&s1
{1, 2}, &S2
{3, 4}}
490 want
: `{"X":2,"Y":4}`,
492 // Exported fields on embedded unexported structs at multiple levels
493 // of nesting should still be serialized.
494 label
: "NestedStructAndInts",
495 makeInput
: func() any
{
514 return S
{s1
{1, 2, s2
{3, 4}}, 6}
516 want
: `{"MyInt1":1,"MyInt2":3}`,
518 // If an anonymous struct pointer field is nil, we should ignore
519 // the embedded fields behind it. Not properly doing so may
520 // result in the wrong output or reflect panics.
521 label
: "EmbeddedFieldBehindNilPointer",
522 makeInput
: func() any
{
524 S2
struct{ Field
string }
532 for _
, tt
:= range tests
{
533 t
.Run(tt
.label
, func(t
*testing
.T
) {
534 b
, err
:= Marshal(tt
.makeInput())
536 t
.Fatalf("Marshal() = %v, want nil error", err
)
538 if string(b
) != tt
.want
{
539 t
.Fatalf("Marshal() = %q, want %q", b
, tt
.want
)
558 // Legal Go: We never use the repeated embedded field (S).
565 // golang.org/issue/16042.
566 // Even if a nil interface value is passed in, as long as
567 // it implements Marshaler, it should be marshaled.
568 type nilJSONMarshaler
string
570 func (nm
*nilJSONMarshaler
) MarshalJSON() ([]byte, error
) {
572 return Marshal("0zenil0")
574 return Marshal("zenil:" + string(*nm
))
577 // golang.org/issue/34235.
578 // Even if a nil interface value is passed in, as long as
579 // it implements encoding.TextMarshaler, it should be marshaled.
580 type nilTextMarshaler
string
582 func (nm
*nilTextMarshaler
) MarshalText() ([]byte, error
) {
584 return []byte("0zenil0"), nil
586 return []byte("zenil:" + string(*nm
)), nil
589 // See golang.org/issue/16042 and golang.org/issue/34235.
590 func TestNilMarshal(t
*testing
.T
) {
591 testCases
:= []struct {
595 {v
: nil, want
: `null`},
596 {v
: new(float64), want
: `0`},
597 {v
: []any(nil), want
: `null`},
598 {v
: []string(nil), want
: `null`},
599 {v
: map[string]string(nil), want
: `null`},
600 {v
: []byte(nil), want
: `null`},
601 {v
: struct{ M
string }{"gopher"}, want
: `{"M":"gopher"}`},
602 {v
: struct{ M Marshaler
}{}, want
: `{"M":null}`},
603 {v
: struct{ M Marshaler
}{(*nilJSONMarshaler
)(nil)}, want
: `{"M":"0zenil0"}`},
604 {v
: struct{ M any
}{(*nilJSONMarshaler
)(nil)}, want
: `{"M":null}`},
605 {v
: struct{ M encoding
.TextMarshaler
}{}, want
: `{"M":null}`},
606 {v
: struct{ M encoding
.TextMarshaler
}{(*nilTextMarshaler
)(nil)}, want
: `{"M":"0zenil0"}`},
607 {v
: struct{ M any
}{(*nilTextMarshaler
)(nil)}, want
: `{"M":null}`},
610 for _
, tt
:= range testCases
{
611 out
, err
:= Marshal(tt
.v
)
612 if err
!= nil ||
string(out
) != tt
.want
{
613 t
.Errorf("Marshal(%#v) = %#q, %#v, want %#q, nil", tt
.v
, out
, err
, tt
.want
)
620 func TestEmbeddedBug(t
*testing
.T
) {
627 t
.Fatal("Marshal:", err
)
632 t
.Fatalf("Marshal: got %s want %s", got
, want
)
634 // Now check that the duplicate field, S, does not appear.
640 t
.Fatal("Marshal:", err
)
645 t
.Fatalf("Marshal: got %s want %s", got
, want
)
649 type BugD
struct { // Same as BugA after tagging.
650 XXX
string `json:"S"`
653 // BugD's tagged S field should dominate BugA's.
659 // Test that a field with a tag dominates untagged fields.
660 func TestTaggedFieldDominates(t
*testing
.T
) {
667 t
.Fatal("Marshal:", err
)
669 want
:= `{"S":"BugD"}`
672 t
.Fatalf("Marshal: got %s want %s", got
, want
)
676 // There are no tags here, so S should not appear.
680 BugY
// Contains a tagged S field through BugD; should not dominate.
683 func TestDuplicatedFieldDisappears(t
*testing
.T
) {
694 t
.Fatal("Marshal:", err
)
699 t
.Fatalf("Marshal: got %s want %s", got
, want
)
703 func TestStringBytes(t
*testing
.T
) {
705 // Test that encodeState.stringBytes and encodeState.string use the same encoding.
707 for i
:= '\u0000'; i
<= unicode
.MaxRune
; i
++ {
708 if testing
.Short() && i
> 1000 {
713 s
:= string(r
) + "\xff\xff\xffhello" // some invalid UTF-8 too
715 for _
, escapeHTML
:= range []bool{true, false} {
717 es
.string(s
, escapeHTML
)
719 esBytes
:= &encodeState
{}
720 esBytes
.stringBytes([]byte(s
), escapeHTML
)
722 enc
:= es
.Buffer
.String()
723 encBytes
:= esBytes
.Buffer
.String()
726 for i
< len(enc
) && i
< len(encBytes
) && enc
[i
] == encBytes
[i
] {
730 encBytes
= encBytes
[i
:]
732 for i
< len(enc
) && i
< len(encBytes
) && enc
[len(enc
)-i
-1] == encBytes
[len(encBytes
)-i
-1] {
735 enc
= enc
[:len(enc
)-i
]
736 encBytes
= encBytes
[:len(encBytes
)-i
]
739 enc
= enc
[:20] + "..."
741 if len(encBytes
) > 20 {
742 encBytes
= encBytes
[:20] + "..."
745 t
.Errorf("with escapeHTML=%t, encodings differ at %#q vs %#q",
746 escapeHTML
, enc
, encBytes
)
751 func TestIssue10281(t
*testing
.T
) {
755 x
:= Foo
{Number(`invalid`)}
757 b
, err
:= Marshal(&x
)
759 t
.Errorf("Marshal(&x) = %#q; want error", b
)
763 func TestHTMLEscape(t
*testing
.T
) {
764 var b
, want bytes
.Buffer
765 m
:= `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
766 want
.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
767 HTMLEscape(&b
, []byte(m
))
768 if !bytes
.Equal(b
.Bytes(), want
.Bytes()) {
769 t
.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b
.Bytes(), want
.Bytes())
773 // golang.org/issue/8582
774 func TestEncodePointerString(t
*testing
.T
) {
775 type stringPointer
struct {
776 N
*int64 `json:"n,string"`
779 b
, err
:= Marshal(stringPointer
{N
: &n
})
781 t
.Fatalf("Marshal: %v", err
)
783 if got
, want
:= string(b
), `{"n":"42"}`; got
!= want
{
784 t
.Errorf("Marshal = %s, want %s", got
, want
)
786 var back stringPointer
787 err
= Unmarshal(b
, &back
)
789 t
.Fatalf("Unmarshal: %v", err
)
792 t
.Fatalf("Unmarshaled nil N field")
795 t
.Fatalf("*N = %d; want 42", *back
.N
)
799 var encodeStringTests
= []struct {
803 {"\x00", `"\u0000"`},
804 {"\x01", `"\u0001"`},
805 {"\x02", `"\u0002"`},
806 {"\x03", `"\u0003"`},
807 {"\x04", `"\u0004"`},
808 {"\x05", `"\u0005"`},
809 {"\x06", `"\u0006"`},
810 {"\x07", `"\u0007"`},
811 {"\x08", `"\u0008"`},
814 {"\x0b", `"\u000b"`},
815 {"\x0c", `"\u000c"`},
817 {"\x0e", `"\u000e"`},
818 {"\x0f", `"\u000f"`},
819 {"\x10", `"\u0010"`},
820 {"\x11", `"\u0011"`},
821 {"\x12", `"\u0012"`},
822 {"\x13", `"\u0013"`},
823 {"\x14", `"\u0014"`},
824 {"\x15", `"\u0015"`},
825 {"\x16", `"\u0016"`},
826 {"\x17", `"\u0017"`},
827 {"\x18", `"\u0018"`},
828 {"\x19", `"\u0019"`},
829 {"\x1a", `"\u001a"`},
830 {"\x1b", `"\u001b"`},
831 {"\x1c", `"\u001c"`},
832 {"\x1d", `"\u001d"`},
833 {"\x1e", `"\u001e"`},
834 {"\x1f", `"\u001f"`},
837 func TestEncodeString(t
*testing
.T
) {
838 for _
, tt
:= range encodeStringTests
{
839 b
, err
:= Marshal(tt
.in
)
841 t
.Errorf("Marshal(%q): %v", tt
.in
, err
)
846 t
.Errorf("Marshal(%q) = %#q, want %#q", tt
.in
, out
, tt
.out
)
853 func (b jsonbyte
) MarshalJSON() ([]byte, error
) { return tenc(`{"JB":%d}`, b
) }
857 func (b textbyte
) MarshalText() ([]byte, error
) { return tenc(`TB:%d`, b
) }
861 func (i jsonint
) MarshalJSON() ([]byte, error
) { return tenc(`{"JI":%d}`, i
) }
865 func (i textint
) MarshalText() ([]byte, error
) { return tenc(`TI:%d`, i
) }
867 func tenc(format
string, a
...any
) ([]byte, error
) {
869 fmt
.Fprintf(&buf
, format
, a
...)
870 return buf
.Bytes(), nil
873 type textfloat
float64
875 func (f textfloat
) MarshalText() ([]byte, error
) { return tenc(`TF:%0.2f`, f
) }
878 func TestEncodeBytekind(t
*testing
.T
) {
879 testdata
:= []struct {
884 {jsonbyte(7), `{"JB":7}`},
885 {textbyte(4), `"TB:4"`},
886 {jsonint(5), `{"JI":5}`},
887 {textint(1), `"TI:1"`},
888 {[]byte{0, 1}, `"AAE="`},
889 {[]jsonbyte
{0, 1}, `[{"JB":0},{"JB":1}]`},
890 {[][]jsonbyte
{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`},
891 {[]textbyte
{2, 3}, `["TB:2","TB:3"]`},
892 {[]jsonint
{5, 4}, `[{"JI":5},{"JI":4}]`},
893 {[]textint
{9, 3}, `["TI:9","TI:3"]`},
894 {[]int{9, 3}, `[9,3]`},
895 {[]textfloat
{12, 3}, `["TF:12.00","TF:3.00"]`},
897 for _
, d
:= range testdata
{
898 js
, err
:= Marshal(d
.data
)
903 got
, want
:= string(js
), d
.want
905 t
.Errorf("got %s, want %s", got
, want
)
910 func TestTextMarshalerMapKeysAreSorted(t
*testing
.T
) {
911 b
, err
:= Marshal(map[unmarshalerText
]int{
918 t
.Fatalf("Failed to Marshal text.Marshaler: %v", err
)
920 const want
= `{"a:z":3,"x:y":1,"y:x":2,"z:a":4}`
921 if string(b
) != want
{
922 t
.Errorf("Marshal map with text.Marshaler keys: got %#q, want %#q", b
, want
)
926 // https://golang.org/issue/33675
927 func TestNilMarshalerTextMapKey(t
*testing
.T
) {
928 b
, err
:= Marshal(map[*unmarshalerText
]int{
929 (*unmarshalerText
)(nil): 1,
933 t
.Fatalf("Failed to Marshal *text.Marshaler: %v", err
)
935 const want
= `{"":1,"A:B":2}`
936 if string(b
) != want
{
937 t
.Errorf("Marshal map with *text.Marshaler keys: got %#q, want %#q", b
, want
)
941 var re
= regexp
.MustCompile
943 // syntactic checks on form of marshaled floating point numbers.
944 var badFloatREs
= []*regexp
.Regexp
{
945 re(`p`), // no binary exponential notation
946 re(`^\+`), // no leading + sign
947 re(`^-?0[^.]`), // no unnecessary leading zeros
948 re(`^-?\.`), // leading zero required before decimal point
949 re(`\.(e|$)`), // no trailing decimal
950 re(`\.[0-9]+0(e|$)`), // no trailing zero in fraction
951 re(`^-?(0|[0-9]{2,})\..*e`), // exponential notation must have normalized mantissa
952 re(`e[0-9]`), // positive exponent must be signed
953 re(`e[+-]0`), // exponent must not have leading zeros
954 re(`e-[1-6]$`), // not tiny enough for exponential notation
955 re(`e+(.|1.|20)$`), // not big enough for exponential notation
956 re(`^-?0\.0000000`), // too tiny, should use exponential notation
957 re(`^-?[0-9]{22}`), // too big, should use exponential notation
958 re(`[1-9][0-9]{16}[1-9]`), // too many significant digits in integer
959 re(`[1-9][0-9.]{17}[1-9]`), // too many significant digits in decimal
960 // below here for float32 only
961 re(`[1-9][0-9]{8}[1-9]`), // too many significant digits in integer
962 re(`[1-9][0-9.]{9}[1-9]`), // too many significant digits in decimal
965 func TestMarshalFloat(t
*testing
.T
) {
968 test
:= func(f
float64, bits
int) {
971 f
= float64(float32(f
)) // round
974 bout
, err
:= Marshal(vf
)
976 t
.Errorf("Marshal(%T(%g)): %v", vf
, vf
, err
)
982 // result must convert back to the same float
983 g
, err
:= strconv
.ParseFloat(out
, bits
)
985 t
.Errorf("Marshal(%T(%g)) = %q, cannot parse back: %v", vf
, vf
, out
, err
)
989 if f
!= g || fmt
.Sprint(f
) != fmt
.Sprint(g
) { // fmt.Sprint handles ±0
990 t
.Errorf("Marshal(%T(%g)) = %q (is %g, not %g)", vf
, vf
, out
, float32(g
), vf
)
997 bad
= bad
[:len(bad
)-2]
999 for _
, re
:= range bad
{
1000 if re
.MatchString(out
) {
1001 t
.Errorf("Marshal(%T(%g)) = %q, must not match /%s/", vf
, vf
, out
, re
)
1009 bigger
= math
.Inf(+1)
1010 smaller
= math
.Inf(-1)
1013 var digits
= "1.2345678901234567890123"
1014 for i
:= len(digits
); i
>= 2; i
-- {
1015 if testing
.Short() && i
< len(digits
)-4 {
1018 for exp
:= -30; exp
<= 30; exp
++ {
1019 for _
, sign
:= range "+-" {
1020 for bits
:= 32; bits
<= 64; bits
+= 32 {
1021 s
:= fmt
.Sprintf("%c%se%d", sign
, digits
[:i
], exp
)
1022 f
, err
:= strconv
.ParseFloat(s
, bits
)
1026 next
:= math
.Nextafter
1028 next
= func(g
, h
float64) float64 {
1029 return float64(math
.Nextafter32(float32(g
), float32(h
)))
1033 test(next(f
, bigger
), bits
)
1034 test(next(f
, smaller
), bits
)
1036 t
.Fatalf("stopping test early")
1043 test(math
.Copysign(0, -1), 64)
1045 test(math
.Copysign(0, -1), 32)
1048 func TestMarshalRawMessageValue(t
*testing
.T
) {
1051 M RawMessage
`json:",omitempty"`
1054 M
*RawMessage
`json:",omitempty"`
1059 rawNil
= RawMessage(nil)
1060 rawEmpty
= RawMessage([]byte{})
1061 rawText
= RawMessage([]byte(`"foo"`))
1069 // Test with nil RawMessage.
1070 {rawNil
, "null", true},
1071 {&rawNil
, "null", true},
1072 {[]any
{rawNil
}, "[null]", true},
1073 {&[]any
{rawNil
}, "[null]", true},
1074 {[]any
{&rawNil
}, "[null]", true},
1075 {&[]any
{&rawNil
}, "[null]", true},
1076 {struct{ M RawMessage
}{rawNil
}, `{"M":null}`, true},
1077 {&struct{ M RawMessage
}{rawNil
}, `{"M":null}`, true},
1078 {struct{ M
*RawMessage
}{&rawNil
}, `{"M":null}`, true},
1079 {&struct{ M
*RawMessage
}{&rawNil
}, `{"M":null}`, true},
1080 {map[string]any
{"M": rawNil
}, `{"M":null}`, true},
1081 {&map[string]any
{"M": rawNil
}, `{"M":null}`, true},
1082 {map[string]any
{"M": &rawNil
}, `{"M":null}`, true},
1083 {&map[string]any
{"M": &rawNil
}, `{"M":null}`, true},
1084 {T1
{rawNil
}, "{}", true},
1085 {T2
{&rawNil
}, `{"M":null}`, true},
1086 {&T1
{rawNil
}, "{}", true},
1087 {&T2
{&rawNil
}, `{"M":null}`, true},
1089 // Test with empty, but non-nil, RawMessage.
1090 {rawEmpty
, "", false},
1091 {&rawEmpty
, "", false},
1092 {[]any
{rawEmpty
}, "", false},
1093 {&[]any
{rawEmpty
}, "", false},
1094 {[]any
{&rawEmpty
}, "", false},
1095 {&[]any
{&rawEmpty
}, "", false},
1096 {struct{ X RawMessage
}{rawEmpty
}, "", false},
1097 {&struct{ X RawMessage
}{rawEmpty
}, "", false},
1098 {struct{ X
*RawMessage
}{&rawEmpty
}, "", false},
1099 {&struct{ X
*RawMessage
}{&rawEmpty
}, "", false},
1100 {map[string]any
{"nil": rawEmpty
}, "", false},
1101 {&map[string]any
{"nil": rawEmpty
}, "", false},
1102 {map[string]any
{"nil": &rawEmpty
}, "", false},
1103 {&map[string]any
{"nil": &rawEmpty
}, "", false},
1104 {T1
{rawEmpty
}, "{}", true},
1105 {T2
{&rawEmpty
}, "", false},
1106 {&T1
{rawEmpty
}, "{}", true},
1107 {&T2
{&rawEmpty
}, "", false},
1109 // Test with RawMessage with some text.
1111 // The tests below marked with Issue6458 used to generate "ImZvbyI=" instead "foo".
1112 // This behavior was intentionally changed in Go 1.8.
1113 // See https://golang.org/issues/14493#issuecomment-255857318
1114 {rawText
, `"foo"`, true}, // Issue6458
1115 {&rawText
, `"foo"`, true},
1116 {[]any
{rawText
}, `["foo"]`, true}, // Issue6458
1117 {&[]any
{rawText
}, `["foo"]`, true}, // Issue6458
1118 {[]any
{&rawText
}, `["foo"]`, true},
1119 {&[]any
{&rawText
}, `["foo"]`, true},
1120 {struct{ M RawMessage
}{rawText
}, `{"M":"foo"}`, true}, // Issue6458
1121 {&struct{ M RawMessage
}{rawText
}, `{"M":"foo"}`, true},
1122 {struct{ M
*RawMessage
}{&rawText
}, `{"M":"foo"}`, true},
1123 {&struct{ M
*RawMessage
}{&rawText
}, `{"M":"foo"}`, true},
1124 {map[string]any
{"M": rawText
}, `{"M":"foo"}`, true}, // Issue6458
1125 {&map[string]any
{"M": rawText
}, `{"M":"foo"}`, true}, // Issue6458
1126 {map[string]any
{"M": &rawText
}, `{"M":"foo"}`, true},
1127 {&map[string]any
{"M": &rawText
}, `{"M":"foo"}`, true},
1128 {T1
{rawText
}, `{"M":"foo"}`, true}, // Issue6458
1129 {T2
{&rawText
}, `{"M":"foo"}`, true},
1130 {&T1
{rawText
}, `{"M":"foo"}`, true},
1131 {&T2
{&rawText
}, `{"M":"foo"}`, true},
1134 for i
, tt
:= range tests
{
1135 b
, err
:= Marshal(tt
.in
)
1136 if ok
:= (err
== nil); ok
!= tt
.ok
{
1138 t
.Errorf("test %d, unexpected failure: %v", i
, err
)
1140 t
.Errorf("test %d, unexpected success", i
)
1143 if got
:= string(b
); got
!= tt
.want
{
1144 t
.Errorf("test %d, Marshal(%#v) = %q, want %q", i
, tt
.in
, got
, tt
.want
)
1149 type marshalPanic
struct{}
1151 func (marshalPanic
) MarshalJSON() ([]byte, error
) { panic(0xdead) }
1153 func TestMarshalPanic(t
*testing
.T
) {
1155 if got
:= recover(); !reflect
.DeepEqual(got
, 0xdead) {
1156 t
.Errorf("panic() = (%T)(%v), want 0xdead", got
, got
)
1159 Marshal(&marshalPanic
{})
1160 t
.Error("Marshal should have panicked")
1163 func TestMarshalUncommonFieldNames(t
*testing
.T
) {
1167 b
, err
:= Marshal(v
)
1169 t
.Fatal("Marshal:", err
)
1171 want
:= `{"A0":0,"À":0,"Aβ":0}`
1174 t
.Fatalf("Marshal: got %s want %s", got
, want
)
1178 func TestMarshalerError(t
*testing
.T
) {
1179 s
:= "test variable"
1180 st
:= reflect
.TypeOf(s
)
1181 errText
:= "json: test error"
1188 &MarshalerError
{st
, fmt
.Errorf(errText
), ""},
1189 "json: error calling MarshalJSON for type " + st
.String() + ": " + errText
,
1192 &MarshalerError
{st
, fmt
.Errorf(errText
), "TestMarshalerError"},
1193 "json: error calling TestMarshalerError for type " + st
.String() + ": " + errText
,
1197 for i
, tt
:= range tests
{
1198 got
:= tt
.err
.Error()
1200 t
.Errorf("MarshalerError test %d, got: %s, want: %s", i
, got
, tt
.want
)