1
2
3
4
5 package json
6
7 import (
8 "bytes"
9 "encoding"
10 "fmt"
11 "log"
12 "math"
13 "reflect"
14 "regexp"
15 "strconv"
16 "testing"
17 "unicode"
18 )
19
20 type Optionals struct {
21 Sr string `json:"sr"`
22 So string `json:"so,omitempty"`
23 Sw string `json:"-"`
24
25 Ir int `json:"omitempty"`
26 Io int `json:"io,omitempty"`
27
28 Slr []string `json:"slr,random"`
29 Slo []string `json:"slo,omitempty"`
30
31 Mr map[string]interface{} `json:"mr"`
32 Mo map[string]interface{} `json:",omitempty"`
33
34 Fr float64 `json:"fr"`
35 Fo float64 `json:"fo,omitempty"`
36
37 Br bool `json:"br"`
38 Bo bool `json:"bo,omitempty"`
39
40 Ur uint `json:"ur"`
41 Uo uint `json:"uo,omitempty"`
42
43 Str struct{} `json:"str"`
44 Sto struct{} `json:"sto,omitempty"`
45 }
46
47 var optionalsExpected = `{
48 "sr": "",
49 "omitempty": 0,
50 "slr": null,
51 "mr": {},
52 "fr": 0,
53 "br": false,
54 "ur": 0,
55 "str": {},
56 "sto": {}
57 }`
58
59 func TestOmitEmpty(t *testing.T) {
60 var o Optionals
61 o.Sw = "something"
62 o.Mr = map[string]interface{}{}
63 o.Mo = map[string]interface{}{}
64
65 got, err := MarshalIndent(&o, "", " ")
66 if err != nil {
67 t.Fatal(err)
68 }
69 if got := string(got); got != optionalsExpected {
70 t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
71 }
72 }
73
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"`
80 }
81
82 func TestRoundtripStringTag(t *testing.T) {
83 tests := []struct {
84 name string
85 in StringTag
86 want string
87 }{
88 {
89 name: "AllTypes",
90 in: StringTag{
91 BoolStr: true,
92 IntStr: 42,
93 UintptrStr: 44,
94 StrStr: "xzbit",
95 NumberStr: "46",
96 },
97 want: `{
98 "BoolStr": "true",
99 "IntStr": "42",
100 "UintptrStr": "44",
101 "StrStr": "\"xzbit\"",
102 "NumberStr": "46"
103 }`,
104 },
105 {
106
107 name: "StringDoubleEscapes",
108 in: StringTag{
109 StrStr: "\b\f\n\r\t\"\\",
110 NumberStr: "0",
111 },
112 want: `{
113 "BoolStr": "false",
114 "IntStr": "0",
115 "UintptrStr": "0",
116 "StrStr": "\"\\u0008\\u000c\\n\\r\\t\\\"\\\\\"",
117 "NumberStr": "0"
118 }`,
119 },
120 }
121 for _, test := range tests {
122 t.Run(test.name, func(t *testing.T) {
123
124
125 got, err := MarshalIndent(&test.in, "\t\t\t", "\t")
126 if err != nil {
127 t.Fatal(err)
128 }
129 if got := string(got); got != test.want {
130 t.Fatalf(" got: %s\nwant: %s\n", got, test.want)
131 }
132
133
134 var s2 StringTag
135 if err := Unmarshal(got, &s2); err != nil {
136 t.Fatalf("Decode: %v", err)
137 }
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)
140 }
141 })
142 }
143 }
144
145
146 type renamedByte byte
147 type renamedByteSlice []byte
148 type renamedRenamedByteSlice []renamedByte
149
150 func TestEncodeRenamedByteSlice(t *testing.T) {
151 s := renamedByteSlice("abc")
152 result, err := Marshal(s)
153 if err != nil {
154 t.Fatal(err)
155 }
156 expect := `"YWJj"`
157 if string(result) != expect {
158 t.Errorf(" got %s want %s", result, expect)
159 }
160 r := renamedRenamedByteSlice("abc")
161 result, err = Marshal(r)
162 if err != nil {
163 t.Fatal(err)
164 }
165 if string(result) != expect {
166 t.Errorf(" got %s want %s", result, expect)
167 }
168 }
169
170 type SamePointerNoCycle struct {
171 Ptr1, Ptr2 *SamePointerNoCycle
172 }
173
174 var samePointerNoCycle = &SamePointerNoCycle{}
175
176 type PointerCycle struct {
177 Ptr *PointerCycle
178 }
179
180 var pointerCycle = &PointerCycle{}
181
182 type PointerCycleIndirect struct {
183 Ptrs []interface{}
184 }
185
186 type RecursiveSlice []RecursiveSlice
187
188 var (
189 pointerCycleIndirect = &PointerCycleIndirect{}
190 mapCycle = make(map[string]interface{})
191 sliceCycle = []interface{}{nil}
192 sliceNoCycle = []interface{}{nil, nil}
193 recursiveSliceCycle = []RecursiveSlice{nil}
194 )
195
196 func init() {
197 ptr := &SamePointerNoCycle{}
198 samePointerNoCycle.Ptr1 = ptr
199 samePointerNoCycle.Ptr2 = ptr
200
201 pointerCycle.Ptr = pointerCycle
202 pointerCycleIndirect.Ptrs = []interface{}{pointerCycleIndirect}
203
204 mapCycle["x"] = mapCycle
205 sliceCycle[0] = sliceCycle
206 sliceNoCycle[1] = sliceNoCycle[:1]
207 for i := startDetectingCyclesAfter; i > 0; i-- {
208 sliceNoCycle = []interface{}{sliceNoCycle}
209 }
210 recursiveSliceCycle[0] = recursiveSliceCycle
211 }
212
213 func TestSamePointerNoCycle(t *testing.T) {
214 if _, err := Marshal(samePointerNoCycle); err != nil {
215 t.Fatalf("unexpected error: %v", err)
216 }
217 }
218
219 func TestSliceNoCycle(t *testing.T) {
220 if _, err := Marshal(sliceNoCycle); err != nil {
221 t.Fatalf("unexpected error: %v", err)
222 }
223 }
224
225 var unsupportedValues = []interface{}{
226 math.NaN(),
227 math.Inf(-1),
228 math.Inf(1),
229 pointerCycle,
230 pointerCycleIndirect,
231 mapCycle,
232 sliceCycle,
233 recursiveSliceCycle,
234 }
235
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)
241 }
242 } else {
243 t.Errorf("for %v, expected error", v)
244 }
245 }
246 }
247
248
249 func TestMarshalTextFloatMap(t *testing.T) {
250 m := map[textfloat]string{
251 textfloat(math.NaN()): "1",
252 textfloat(math.NaN()): "1",
253 }
254 got, err := Marshal(m)
255 if err != nil {
256 t.Errorf("Marshal() error: %v", err)
257 }
258 want := `{"TF:NaN":"1","TF:NaN":"1"}`
259 if string(got) != want {
260 t.Errorf("Marshal() = %s, want %s", got, want)
261 }
262 }
263
264
265 type Ref int
266
267 func (*Ref) MarshalJSON() ([]byte, error) {
268 return []byte(`"ref"`), nil
269 }
270
271 func (r *Ref) UnmarshalJSON([]byte) error {
272 *r = 12
273 return nil
274 }
275
276
277 type Val int
278
279 func (Val) MarshalJSON() ([]byte, error) {
280 return []byte(`"val"`), nil
281 }
282
283
284 type RefText int
285
286 func (*RefText) MarshalText() ([]byte, error) {
287 return []byte(`"ref"`), nil
288 }
289
290 func (r *RefText) UnmarshalText([]byte) error {
291 *r = 13
292 return nil
293 }
294
295
296 type ValText int
297
298 func (ValText) MarshalText() ([]byte, error) {
299 return []byte(`"val"`), nil
300 }
301
302 func TestRefValMarshal(t *testing.T) {
303 var s = struct {
304 R0 Ref
305 R1 *Ref
306 R2 RefText
307 R3 *RefText
308 V0 Val
309 V1 *Val
310 V2 ValText
311 V3 *ValText
312 }{
313 R0: 12,
314 R1: new(Ref),
315 R2: 14,
316 R3: new(RefText),
317 V0: 13,
318 V1: new(Val),
319 V2: 15,
320 V3: new(ValText),
321 }
322 const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
323 b, err := Marshal(&s)
324 if err != nil {
325 t.Fatalf("Marshal: %v", err)
326 }
327 if got := string(b); got != want {
328 t.Errorf("got %q, want %q", got, want)
329 }
330 }
331
332
333 type C int
334
335 func (C) MarshalJSON() ([]byte, error) {
336 return []byte(`"<&>"`), nil
337 }
338
339
340 type CText int
341
342 func (CText) MarshalText() ([]byte, error) {
343 return []byte(`"<&>"`), nil
344 }
345
346 func TestMarshalerEscaping(t *testing.T) {
347 var c C
348 want := `"\u003c\u0026\u003e"`
349 b, err := Marshal(c)
350 if err != nil {
351 t.Fatalf("Marshal(c): %v", err)
352 }
353 if got := string(b); got != want {
354 t.Errorf("Marshal(c) = %#q, want %#q", got, want)
355 }
356
357 var ct CText
358 want = `"\"\u003c\u0026\u003e\""`
359 b, err = Marshal(ct)
360 if err != nil {
361 t.Fatalf("Marshal(ct): %v", err)
362 }
363 if got := string(b); got != want {
364 t.Errorf("Marshal(ct) = %#q, want %#q", got, want)
365 }
366 }
367
368 func TestAnonymousFields(t *testing.T) {
369 tests := []struct {
370 label string
371 makeInput func() interface{}
372 want string
373 }{{
374
375
376
377 label: "AmbiguousField",
378 makeInput: func() interface{} {
379 type (
380 S1 struct{ x, X int }
381 S2 struct{ x, X int }
382 S struct {
383 S1
384 S2
385 }
386 )
387 return S{S1{1, 2}, S2{3, 4}}
388 },
389 want: `{}`,
390 }, {
391 label: "DominantField",
392
393
394 makeInput: func() interface{} {
395 type (
396 S1 struct{ x, X int }
397 S2 struct{ x, X int }
398 S struct {
399 S1
400 S2
401 x, X int
402 }
403 )
404 return S{S1{1, 2}, S2{3, 4}, 5, 6}
405 },
406 want: `{"X":6}`,
407 }, {
408
409 label: "UnexportedEmbeddedInt",
410 makeInput: func() interface{} {
411 type (
412 myInt int
413 S struct{ myInt }
414 )
415 return S{5}
416 },
417 want: `{}`,
418 }, {
419
420 label: "ExportedEmbeddedInt",
421 makeInput: func() interface{} {
422 type (
423 MyInt int
424 S struct{ MyInt }
425 )
426 return S{5}
427 },
428 want: `{"MyInt":5}`,
429 }, {
430
431
432 label: "UnexportedEmbeddedIntPointer",
433 makeInput: func() interface{} {
434 type (
435 myInt int
436 S struct{ *myInt }
437 )
438 s := S{new(myInt)}
439 *s.myInt = 5
440 return s
441 },
442 want: `{}`,
443 }, {
444
445
446 label: "ExportedEmbeddedIntPointer",
447 makeInput: func() interface{} {
448 type (
449 MyInt int
450 S struct{ *MyInt }
451 )
452 s := S{new(MyInt)}
453 *s.MyInt = 5
454 return s
455 },
456 want: `{"MyInt":5}`,
457 }, {
458
459
460
461 label: "EmbeddedStruct",
462 makeInput: func() interface{} {
463 type (
464 s1 struct{ x, X int }
465 S2 struct{ y, Y int }
466 S struct {
467 s1
468 S2
469 }
470 )
471 return S{s1{1, 2}, S2{3, 4}}
472 },
473 want: `{"X":2,"Y":4}`,
474 }, {
475
476
477
478 label: "EmbeddedStructPointer",
479 makeInput: func() interface{} {
480 type (
481 s1 struct{ x, X int }
482 S2 struct{ y, Y int }
483 S struct {
484 *s1
485 *S2
486 }
487 )
488 return S{&s1{1, 2}, &S2{3, 4}}
489 },
490 want: `{"X":2,"Y":4}`,
491 }, {
492
493
494 label: "NestedStructAndInts",
495 makeInput: func() interface{} {
496 type (
497 MyInt1 int
498 MyInt2 int
499 myInt int
500 s2 struct {
501 MyInt2
502 myInt
503 }
504 s1 struct {
505 MyInt1
506 myInt
507 s2
508 }
509 S struct {
510 s1
511 myInt
512 }
513 )
514 return S{s1{1, 2, s2{3, 4}}, 6}
515 },
516 want: `{"MyInt1":1,"MyInt2":3}`,
517 }, {
518
519
520
521 label: "EmbeddedFieldBehindNilPointer",
522 makeInput: func() interface{} {
523 type (
524 S2 struct{ Field string }
525 S struct{ *S2 }
526 )
527 return S{}
528 },
529 want: `{}`,
530 }}
531
532 for _, tt := range tests {
533 t.Run(tt.label, func(t *testing.T) {
534 b, err := Marshal(tt.makeInput())
535 if err != nil {
536 t.Fatalf("Marshal() = %v, want nil error", err)
537 }
538 if string(b) != tt.want {
539 t.Fatalf("Marshal() = %q, want %q", b, tt.want)
540 }
541 })
542 }
543 }
544
545 type BugA struct {
546 S string
547 }
548
549 type BugB struct {
550 BugA
551 S string
552 }
553
554 type BugC struct {
555 S string
556 }
557
558
559 type BugX struct {
560 A int
561 BugA
562 BugB
563 }
564
565
566
567
568 type nilJSONMarshaler string
569
570 func (nm *nilJSONMarshaler) MarshalJSON() ([]byte, error) {
571 if nm == nil {
572 return Marshal("0zenil0")
573 }
574 return Marshal("zenil:" + string(*nm))
575 }
576
577
578
579
580 type nilTextMarshaler string
581
582 func (nm *nilTextMarshaler) MarshalText() ([]byte, error) {
583 if nm == nil {
584 return []byte("0zenil0"), nil
585 }
586 return []byte("zenil:" + string(*nm)), nil
587 }
588
589
590 func TestNilMarshal(t *testing.T) {
591 testCases := []struct {
592 v interface{}
593 want string
594 }{
595 {v: nil, want: `null`},
596 {v: new(float64), want: `0`},
597 {v: []interface{}(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 interface{} }{(*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 interface{} }{(*nilTextMarshaler)(nil)}, want: `{"M":null}`},
608 }
609
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)
614 continue
615 }
616 }
617 }
618
619
620 func TestEmbeddedBug(t *testing.T) {
621 v := BugB{
622 BugA{"A"},
623 "B",
624 }
625 b, err := Marshal(v)
626 if err != nil {
627 t.Fatal("Marshal:", err)
628 }
629 want := `{"S":"B"}`
630 got := string(b)
631 if got != want {
632 t.Fatalf("Marshal: got %s want %s", got, want)
633 }
634
635 x := BugX{
636 A: 23,
637 }
638 b, err = Marshal(x)
639 if err != nil {
640 t.Fatal("Marshal:", err)
641 }
642 want = `{"A":23}`
643 got = string(b)
644 if got != want {
645 t.Fatalf("Marshal: got %s want %s", got, want)
646 }
647 }
648
649 type BugD struct {
650 XXX string `json:"S"`
651 }
652
653
654 type BugY struct {
655 BugA
656 BugD
657 }
658
659
660 func TestTaggedFieldDominates(t *testing.T) {
661 v := BugY{
662 BugA{"BugA"},
663 BugD{"BugD"},
664 }
665 b, err := Marshal(v)
666 if err != nil {
667 t.Fatal("Marshal:", err)
668 }
669 want := `{"S":"BugD"}`
670 got := string(b)
671 if got != want {
672 t.Fatalf("Marshal: got %s want %s", got, want)
673 }
674 }
675
676
677 type BugZ struct {
678 BugA
679 BugC
680 BugY
681 }
682
683 func TestDuplicatedFieldDisappears(t *testing.T) {
684 v := BugZ{
685 BugA{"BugA"},
686 BugC{"BugC"},
687 BugY{
688 BugA{"nested BugA"},
689 BugD{"nested BugD"},
690 },
691 }
692 b, err := Marshal(v)
693 if err != nil {
694 t.Fatal("Marshal:", err)
695 }
696 want := `{}`
697 got := string(b)
698 if got != want {
699 t.Fatalf("Marshal: got %s want %s", got, want)
700 }
701 }
702
703 func TestStringBytes(t *testing.T) {
704 t.Parallel()
705
706 var r []rune
707 for i := '\u0000'; i <= unicode.MaxRune; i++ {
708 if testing.Short() && i > 1000 {
709 i = unicode.MaxRune
710 }
711 r = append(r, i)
712 }
713 s := string(r) + "\xff\xff\xffhello"
714
715 for _, escapeHTML := range []bool{true, false} {
716 es := &encodeState{}
717 es.string(s, escapeHTML)
718
719 esBytes := &encodeState{}
720 esBytes.stringBytes([]byte(s), escapeHTML)
721
722 enc := es.Buffer.String()
723 encBytes := esBytes.Buffer.String()
724 if enc != encBytes {
725 i := 0
726 for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] {
727 i++
728 }
729 enc = enc[i:]
730 encBytes = encBytes[i:]
731 i = 0
732 for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] {
733 i++
734 }
735 enc = enc[:len(enc)-i]
736 encBytes = encBytes[:len(encBytes)-i]
737
738 if len(enc) > 20 {
739 enc = enc[:20] + "..."
740 }
741 if len(encBytes) > 20 {
742 encBytes = encBytes[:20] + "..."
743 }
744
745 t.Errorf("with escapeHTML=%t, encodings differ at %#q vs %#q",
746 escapeHTML, enc, encBytes)
747 }
748 }
749 }
750
751 func TestIssue10281(t *testing.T) {
752 type Foo struct {
753 N Number
754 }
755 x := Foo{Number(`invalid`)}
756
757 b, err := Marshal(&x)
758 if err == nil {
759 t.Errorf("Marshal(&x) = %#q; want error", b)
760 }
761 }
762
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())
770 }
771 }
772
773
774 func TestEncodePointerString(t *testing.T) {
775 type stringPointer struct {
776 N *int64 `json:"n,string"`
777 }
778 var n int64 = 42
779 b, err := Marshal(stringPointer{N: &n})
780 if err != nil {
781 t.Fatalf("Marshal: %v", err)
782 }
783 if got, want := string(b), `{"n":"42"}`; got != want {
784 t.Errorf("Marshal = %s, want %s", got, want)
785 }
786 var back stringPointer
787 err = Unmarshal(b, &back)
788 if err != nil {
789 t.Fatalf("Unmarshal: %v", err)
790 }
791 if back.N == nil {
792 t.Fatalf("Unmarshaled nil N field")
793 }
794 if *back.N != 42 {
795 t.Fatalf("*N = %d; want 42", *back.N)
796 }
797 }
798
799 var encodeStringTests = []struct {
800 in string
801 out string
802 }{
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"`},
812 {"\x09", `"\t"`},
813 {"\x0a", `"\n"`},
814 {"\x0b", `"\u000b"`},
815 {"\x0c", `"\u000c"`},
816 {"\x0d", `"\r"`},
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"`},
835 }
836
837 func TestEncodeString(t *testing.T) {
838 for _, tt := range encodeStringTests {
839 b, err := Marshal(tt.in)
840 if err != nil {
841 t.Errorf("Marshal(%q): %v", tt.in, err)
842 continue
843 }
844 out := string(b)
845 if out != tt.out {
846 t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out)
847 }
848 }
849 }
850
851 type jsonbyte byte
852
853 func (b jsonbyte) MarshalJSON() ([]byte, error) { return tenc(`{"JB":%d}`, b) }
854
855 type textbyte byte
856
857 func (b textbyte) MarshalText() ([]byte, error) { return tenc(`TB:%d`, b) }
858
859 type jsonint int
860
861 func (i jsonint) MarshalJSON() ([]byte, error) { return tenc(`{"JI":%d}`, i) }
862
863 type textint int
864
865 func (i textint) MarshalText() ([]byte, error) { return tenc(`TI:%d`, i) }
866
867 func tenc(format string, a ...interface{}) ([]byte, error) {
868 var buf bytes.Buffer
869 fmt.Fprintf(&buf, format, a...)
870 return buf.Bytes(), nil
871 }
872
873 type textfloat float64
874
875 func (f textfloat) MarshalText() ([]byte, error) { return tenc(`TF:%0.2f`, f) }
876
877
878 func TestEncodeBytekind(t *testing.T) {
879 testdata := []struct {
880 data interface{}
881 want string
882 }{
883 {byte(7), "7"},
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"]`},
896 }
897 for _, d := range testdata {
898 js, err := Marshal(d.data)
899 if err != nil {
900 t.Error(err)
901 continue
902 }
903 got, want := string(js), d.want
904 if got != want {
905 t.Errorf("got %s, want %s", got, want)
906 }
907 }
908 }
909
910 func TestTextMarshalerMapKeysAreSorted(t *testing.T) {
911 b, err := Marshal(map[unmarshalerText]int{
912 {"x", "y"}: 1,
913 {"y", "x"}: 2,
914 {"a", "z"}: 3,
915 {"z", "a"}: 4,
916 })
917 if err != nil {
918 t.Fatalf("Failed to Marshal text.Marshaler: %v", err)
919 }
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)
923 }
924 }
925
926
927 func TestNilMarshalerTextMapKey(t *testing.T) {
928 b, err := Marshal(map[*unmarshalerText]int{
929 (*unmarshalerText)(nil): 1,
930 {"A", "B"}: 2,
931 })
932 if err != nil {
933 t.Fatalf("Failed to Marshal *text.Marshaler: %v", err)
934 }
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)
938 }
939 }
940
941 var re = regexp.MustCompile
942
943
944 var badFloatREs = []*regexp.Regexp{
945 re(`p`),
946 re(`^\+`),
947 re(`^-?0[^.]`),
948 re(`^-?\.`),
949 re(`\.(e|$)`),
950 re(`\.[0-9]+0(e|$)`),
951 re(`^-?(0|[0-9]{2,})\..*e`),
952 re(`e[0-9]`),
953 re(`e[+-]0`),
954 re(`e-[1-6]$`),
955 re(`e+(.|1.|20)$`),
956 re(`^-?0\.0000000`),
957 re(`^-?[0-9]{22}`),
958 re(`[1-9][0-9]{16}[1-9]`),
959 re(`[1-9][0-9.]{17}[1-9]`),
960
961 re(`[1-9][0-9]{8}[1-9]`),
962 re(`[1-9][0-9.]{9}[1-9]`),
963 }
964
965 func TestMarshalFloat(t *testing.T) {
966 t.Parallel()
967 nfail := 0
968 test := func(f float64, bits int) {
969 vf := interface{}(f)
970 if bits == 32 {
971 f = float64(float32(f))
972 vf = float32(f)
973 }
974 bout, err := Marshal(vf)
975 if err != nil {
976 t.Errorf("Marshal(%T(%g)): %v", vf, vf, err)
977 nfail++
978 return
979 }
980 out := string(bout)
981
982
983 g, err := strconv.ParseFloat(out, bits)
984 if err != nil {
985 t.Errorf("Marshal(%T(%g)) = %q, cannot parse back: %v", vf, vf, out, err)
986 nfail++
987 return
988 }
989 if f != g || fmt.Sprint(f) != fmt.Sprint(g) {
990 t.Errorf("Marshal(%T(%g)) = %q (is %g, not %g)", vf, vf, out, float32(g), vf)
991 nfail++
992 return
993 }
994
995 bad := badFloatREs
996 if bits == 64 {
997 bad = bad[:len(bad)-2]
998 }
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)
1002 nfail++
1003 return
1004 }
1005 }
1006 }
1007
1008 var (
1009 bigger = math.Inf(+1)
1010 smaller = math.Inf(-1)
1011 )
1012
1013 var digits = "1.2345678901234567890123"
1014 for i := len(digits); i >= 2; i-- {
1015 if testing.Short() && i < len(digits)-4 {
1016 break
1017 }
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)
1023 if err != nil {
1024 log.Fatal(err)
1025 }
1026 next := math.Nextafter
1027 if bits == 32 {
1028 next = func(g, h float64) float64 {
1029 return float64(math.Nextafter32(float32(g), float32(h)))
1030 }
1031 }
1032 test(f, bits)
1033 test(next(f, bigger), bits)
1034 test(next(f, smaller), bits)
1035 if nfail > 50 {
1036 t.Fatalf("stopping test early")
1037 }
1038 }
1039 }
1040 }
1041 }
1042 test(0, 64)
1043 test(math.Copysign(0, -1), 64)
1044 test(0, 32)
1045 test(math.Copysign(0, -1), 32)
1046 }
1047
1048 func TestMarshalRawMessageValue(t *testing.T) {
1049 type (
1050 T1 struct {
1051 M RawMessage `json:",omitempty"`
1052 }
1053 T2 struct {
1054 M *RawMessage `json:",omitempty"`
1055 }
1056 )
1057
1058 var (
1059 rawNil = RawMessage(nil)
1060 rawEmpty = RawMessage([]byte{})
1061 rawText = RawMessage([]byte(`"foo"`))
1062 )
1063
1064 tests := []struct {
1065 in interface{}
1066 want string
1067 ok bool
1068 }{
1069
1070 {rawNil, "null", true},
1071 {&rawNil, "null", true},
1072 {[]interface{}{rawNil}, "[null]", true},
1073 {&[]interface{}{rawNil}, "[null]", true},
1074 {[]interface{}{&rawNil}, "[null]", true},
1075 {&[]interface{}{&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]interface{}{"M": rawNil}, `{"M":null}`, true},
1081 {&map[string]interface{}{"M": rawNil}, `{"M":null}`, true},
1082 {map[string]interface{}{"M": &rawNil}, `{"M":null}`, true},
1083 {&map[string]interface{}{"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},
1088
1089
1090 {rawEmpty, "", false},
1091 {&rawEmpty, "", false},
1092 {[]interface{}{rawEmpty}, "", false},
1093 {&[]interface{}{rawEmpty}, "", false},
1094 {[]interface{}{&rawEmpty}, "", false},
1095 {&[]interface{}{&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]interface{}{"nil": rawEmpty}, "", false},
1101 {&map[string]interface{}{"nil": rawEmpty}, "", false},
1102 {map[string]interface{}{"nil": &rawEmpty}, "", false},
1103 {&map[string]interface{}{"nil": &rawEmpty}, "", false},
1104 {T1{rawEmpty}, "{}", true},
1105 {T2{&rawEmpty}, "", false},
1106 {&T1{rawEmpty}, "{}", true},
1107 {&T2{&rawEmpty}, "", false},
1108
1109
1110
1111
1112
1113
1114 {rawText, `"foo"`, true},
1115 {&rawText, `"foo"`, true},
1116 {[]interface{}{rawText}, `["foo"]`, true},
1117 {&[]interface{}{rawText}, `["foo"]`, true},
1118 {[]interface{}{&rawText}, `["foo"]`, true},
1119 {&[]interface{}{&rawText}, `["foo"]`, true},
1120 {struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true},
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]interface{}{"M": rawText}, `{"M":"foo"}`, true},
1125 {&map[string]interface{}{"M": rawText}, `{"M":"foo"}`, true},
1126 {map[string]interface{}{"M": &rawText}, `{"M":"foo"}`, true},
1127 {&map[string]interface{}{"M": &rawText}, `{"M":"foo"}`, true},
1128 {T1{rawText}, `{"M":"foo"}`, true},
1129 {T2{&rawText}, `{"M":"foo"}`, true},
1130 {&T1{rawText}, `{"M":"foo"}`, true},
1131 {&T2{&rawText}, `{"M":"foo"}`, true},
1132 }
1133
1134 for i, tt := range tests {
1135 b, err := Marshal(tt.in)
1136 if ok := (err == nil); ok != tt.ok {
1137 if err != nil {
1138 t.Errorf("test %d, unexpected failure: %v", i, err)
1139 } else {
1140 t.Errorf("test %d, unexpected success", i)
1141 }
1142 }
1143 if got := string(b); got != tt.want {
1144 t.Errorf("test %d, Marshal(%#v) = %q, want %q", i, tt.in, got, tt.want)
1145 }
1146 }
1147 }
1148
1149 type marshalPanic struct{}
1150
1151 func (marshalPanic) MarshalJSON() ([]byte, error) { panic(0xdead) }
1152
1153 func TestMarshalPanic(t *testing.T) {
1154 defer func() {
1155 if got := recover(); !reflect.DeepEqual(got, 0xdead) {
1156 t.Errorf("panic() = (%T)(%v), want 0xdead", got, got)
1157 }
1158 }()
1159 Marshal(&marshalPanic{})
1160 t.Error("Marshal should have panicked")
1161 }
1162
1163 func TestMarshalUncommonFieldNames(t *testing.T) {
1164 v := struct {
1165 A0, À, Aβ int
1166 }{}
1167 b, err := Marshal(v)
1168 if err != nil {
1169 t.Fatal("Marshal:", err)
1170 }
1171 want := `{"A0":0,"À":0,"Aβ":0}`
1172 got := string(b)
1173 if got != want {
1174 t.Fatalf("Marshal: got %s want %s", got, want)
1175 }
1176 }
1177
1178 func TestMarshalerError(t *testing.T) {
1179 s := "test variable"
1180 st := reflect.TypeOf(s)
1181 errText := "json: test error"
1182
1183 tests := []struct {
1184 err *MarshalerError
1185 want string
1186 }{
1187 {
1188 &MarshalerError{st, fmt.Errorf(errText), ""},
1189 "json: error calling MarshalJSON for type " + st.String() + ": " + errText,
1190 },
1191 {
1192 &MarshalerError{st, fmt.Errorf(errText), "TestMarshalerError"},
1193 "json: error calling TestMarshalerError for type " + st.String() + ": " + errText,
1194 },
1195 }
1196
1197 for i, tt := range tests {
1198 got := tt.err.Error()
1199 if got != tt.want {
1200 t.Errorf("MarshalerError test %d, got: %s, want: %s", i, got, tt.want)
1201 }
1202 }
1203 }
1204
View as plain text