LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package fmt_test | 5 package fmt_test |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 . "fmt" | 9 . "fmt" |
10 "io" | 10 "io" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 | 88 |
89 type S struct { | 89 type S struct { |
90 F F // a struct field that Formats | 90 F F // a struct field that Formats |
91 G G // a struct field that GoStrings | 91 G G // a struct field that GoStrings |
92 } | 92 } |
93 | 93 |
94 type SI struct { | 94 type SI struct { |
95 I interface{} | 95 I interface{} |
96 } | 96 } |
97 | 97 |
98 // A type with a String method with pointer receiver for testing %p | 98 // P is a type with a String method with pointer receiver for testing %p. |
99 type P int | 99 type P int |
100 | 100 |
101 var pValue P | 101 var pValue P |
102 | 102 |
103 func (p *P) String() string { | 103 func (p *P) String() string { |
104 return "String(p)" | 104 return "String(p)" |
105 } | 105 } |
106 | 106 |
107 var b byte | 107 var b byte |
108 | 108 |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 // The "<nil>" show up because maps are printed by | 468 // The "<nil>" show up because maps are printed by |
469 // first obtaining a list of keys and then looking up | 469 // first obtaining a list of keys and then looking up |
470 // each key. Since NaNs can be map keys but cannot | 470 // each key. Since NaNs can be map keys but cannot |
471 // be fetched directly, the lookup fails and returns a | 471 // be fetched directly, the lookup fails and returns a |
472 // zero reflect.Value, which formats as <nil>. | 472 // zero reflect.Value, which formats as <nil>. |
473 // This test is just to check that it shows the two NaNs at all. | 473 // This test is just to check that it shows the two NaNs at all. |
474 {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN
:<nil>]"}, | 474 {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN
:<nil>]"}, |
475 | 475 |
476 // Used to crash because nByte didn't allow for a sign. | 476 // Used to crash because nByte didn't allow for a sign. |
477 {"%b", int64(-1 << 63), "-1000000000000000000000000000000000000000000000
000000000000000000"}, | 477 {"%b", int64(-1 << 63), "-1000000000000000000000000000000000000000000000
000000000000000000"}, |
| 478 |
| 479 // Complex fmt used to leave the plus flag set for future entries in the
array |
| 480 // causing +2+0i and +3+0i instead of 2+0i and 3+0i. |
| 481 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, |
| 482 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, |
478 } | 483 } |
479 | 484 |
480 func TestSprintf(t *testing.T) { | 485 func TestSprintf(t *testing.T) { |
481 for _, tt := range fmttests { | 486 for _, tt := range fmttests { |
482 s := Sprintf(tt.fmt, tt.val) | 487 s := Sprintf(tt.fmt, tt.val) |
483 if i := strings.Index(tt.out, "PTR"); i >= 0 { | 488 if i := strings.Index(tt.out, "PTR"); i >= 0 { |
484 pattern := "PTR" | 489 pattern := "PTR" |
485 chars := "0123456789abcdefABCDEF" | 490 chars := "0123456789abcdefABCDEF" |
486 switch { | 491 switch { |
487 case strings.HasPrefix(tt.out[i:], "PTR_d"): | 492 case strings.HasPrefix(tt.out[i:], "PTR_d"): |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 // For %g we use a float32, not float64, to guarantee passing the argume
nt | 578 // For %g we use a float32, not float64, to guarantee passing the argume
nt |
574 // does not need to allocate memory to store the result in a pointer-siz
ed word. | 579 // does not need to allocate memory to store the result in a pointer-siz
ed word. |
575 {2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, | 580 {2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, |
576 {0, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mal
locBuf, "%x %x %x", 7, 8, 9) }}, | 581 {0, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mal
locBuf, "%x %x %x", 7, 8, 9) }}, |
577 {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf
, "%s", "hello") }}, | 582 {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf
, "%s", "hello") }}, |
578 } | 583 } |
579 | 584 |
580 var _ bytes.Buffer | 585 var _ bytes.Buffer |
581 | 586 |
582 func TestCountMallocs(t *testing.T) { | 587 func TestCountMallocs(t *testing.T) { |
583 const N = 100 | |
584 | |
585 for _, mt := range mallocTest { | 588 for _, mt := range mallocTest { |
586 » » mallocs := testing.AllocsPerRun(N, mt.fn) | 589 » » mallocs := testing.AllocsPerRun(100, mt.fn) |
587 if got, max := mallocs, float64(mt.count); got > max { | 590 if got, max := mallocs, float64(mt.count); got > max { |
588 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, m
ax) | 591 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, m
ax) |
589 } | 592 } |
590 } | 593 } |
591 } | 594 } |
592 | 595 |
593 type flagPrinter struct{} | 596 type flagPrinter struct{} |
594 | 597 |
595 func (*flagPrinter) Format(f State, c rune) { | 598 func (*flagPrinter) Format(f State, c rune) { |
596 s := "%" | 599 s := "%" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 {"%+v", "{a:abc b:def c:123}"}, | 657 {"%+v", "{a:abc b:def c:123}"}, |
655 } | 658 } |
656 for _, tt := range tests { | 659 for _, tt := range tests { |
657 out := Sprintf(tt.fmt, s) | 660 out := Sprintf(tt.fmt, s) |
658 if out != tt.out { | 661 if out != tt.out { |
659 t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, t
t.out) | 662 t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, t
t.out) |
660 } | 663 } |
661 } | 664 } |
662 } | 665 } |
663 | 666 |
664 // Check map printing using substrings so we don't depend on the print order. | 667 // presentInMap checks map printing using substrings so we don't depend on the |
| 668 // print order. |
665 func presentInMap(s string, a []string, t *testing.T) { | 669 func presentInMap(s string, a []string, t *testing.T) { |
666 for i := 0; i < len(a); i++ { | 670 for i := 0; i < len(a); i++ { |
667 loc := strings.Index(s, a[i]) | 671 loc := strings.Index(s, a[i]) |
668 if loc < 0 { | 672 if loc < 0 { |
669 t.Errorf("map print: expected to find %q in %q", a[i], s
) | 673 t.Errorf("map print: expected to find %q in %q", a[i], s
) |
670 } | 674 } |
671 // make sure the match ends here | 675 // make sure the match ends here |
672 loc += len(a[i]) | 676 loc += len(a[i]) |
673 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') { | 677 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') { |
674 t.Errorf("map print: %q not properly terminated in %q",
a[i], s) | 678 t.Errorf("map print: %q not properly terminated in %q",
a[i], s) |
(...skipping 20 matching lines...) Expand all Loading... |
695 if s != emptyMapStr { | 699 if s != emptyMapStr { |
696 t.Errorf("nil map printed as %q not %q", s, emptyMapStr) | 700 t.Errorf("nil map printed as %q not %q", s, emptyMapStr) |
697 } | 701 } |
698 m = make(map[string]int) | 702 m = make(map[string]int) |
699 s = Sprint(m) | 703 s = Sprint(m) |
700 if s != emptyMapStr { | 704 if s != emptyMapStr { |
701 t.Errorf("empty map printed as %q not %q", s, emptyMapStr) | 705 t.Errorf("empty map printed as %q not %q", s, emptyMapStr) |
702 } | 706 } |
703 } | 707 } |
704 | 708 |
705 // Check that Sprint (and hence Print, Fprint) puts spaces in the right places, | 709 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the |
706 // that is, between arg pairs in which neither is a string. | 710 // right places, that is, between arg pairs in which neither is a string. |
707 func TestBlank(t *testing.T) { | 711 func TestBlank(t *testing.T) { |
708 got := Sprint("<", 1, ">:", 1, 2, 3, "!") | 712 got := Sprint("<", 1, ">:", 1, 2, 3, "!") |
709 expect := "<1>:1 2 3!" | 713 expect := "<1>:1 2 3!" |
710 if got != expect { | 714 if got != expect { |
711 t.Errorf("got %q expected %q", got, expect) | 715 t.Errorf("got %q expected %q", got, expect) |
712 } | 716 } |
713 } | 717 } |
714 | 718 |
715 // Check that Sprintln (and hence Println, Fprintln) puts spaces in the right pl
aces, | 719 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in |
716 // that is, between all arg pairs. | 720 // the right places, that is, between all arg pairs. |
717 func TestBlankln(t *testing.T) { | 721 func TestBlankln(t *testing.T) { |
718 got := Sprintln("<", 1, ">:", 1, 2, 3, "!") | 722 got := Sprintln("<", 1, ">:", 1, 2, 3, "!") |
719 expect := "< 1 >: 1 2 3 !\n" | 723 expect := "< 1 >: 1 2 3 !\n" |
720 if got != expect { | 724 if got != expect { |
721 t.Errorf("got %q expected %q", got, expect) | 725 t.Errorf("got %q expected %q", got, expect) |
722 } | 726 } |
723 } | 727 } |
724 | 728 |
725 // Check Formatter with Sprint, Sprintln, Sprintf | 729 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf. |
726 func TestFormatterPrintln(t *testing.T) { | 730 func TestFormatterPrintln(t *testing.T) { |
727 f := F(1) | 731 f := F(1) |
728 expect := "<v=F(1)>\n" | 732 expect := "<v=F(1)>\n" |
729 s := Sprint(f, "\n") | 733 s := Sprint(f, "\n") |
730 if s != expect { | 734 if s != expect { |
731 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expe
ct, s) | 735 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expe
ct, s) |
732 } | 736 } |
733 s = Sprintln(f) | 737 s = Sprintln(f) |
734 if s != expect { | 738 if s != expect { |
735 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", ex
pect, s) | 739 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", ex
pect, s) |
(...skipping 28 matching lines...) Expand all Loading... |
764 | 768 |
765 func TestWidthAndPrecision(t *testing.T) { | 769 func TestWidthAndPrecision(t *testing.T) { |
766 for _, tt := range startests { | 770 for _, tt := range startests { |
767 s := Sprintf(tt.fmt, tt.in...) | 771 s := Sprintf(tt.fmt, tt.in...) |
768 if s != tt.out { | 772 if s != tt.out { |
769 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) | 773 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) |
770 } | 774 } |
771 } | 775 } |
772 } | 776 } |
773 | 777 |
774 // A type that panics in String. | 778 // Panic is a type that panics in String. |
775 type Panic struct { | 779 type Panic struct { |
776 message interface{} | 780 message interface{} |
777 } | 781 } |
778 | 782 |
779 // Value receiver. | 783 // Value receiver. |
780 func (p Panic) GoString() string { | 784 func (p Panic) GoString() string { |
781 panic(p.message) | 785 panic(p.message) |
782 } | 786 } |
783 | 787 |
784 // Value receiver. | 788 // Value receiver. |
785 func (p Panic) String() string { | 789 func (p Panic) String() string { |
786 panic(p.message) | 790 panic(p.message) |
787 } | 791 } |
788 | 792 |
789 // A type that panics in Format. | 793 // PanicF is a type that panics in Format. |
790 type PanicF struct { | 794 type PanicF struct { |
791 message interface{} | 795 message interface{} |
792 } | 796 } |
793 | 797 |
794 // Value receiver. | 798 // Value receiver. |
795 func (p PanicF) Format(f State, c rune) { | 799 func (p PanicF) Format(f State, c rune) { |
796 panic(p.message) | 800 panic(p.message) |
797 } | 801 } |
798 | 802 |
799 var panictests = []struct { | 803 var panictests = []struct { |
(...skipping 17 matching lines...) Expand all Loading... |
817 | 821 |
818 func TestPanics(t *testing.T) { | 822 func TestPanics(t *testing.T) { |
819 for _, tt := range panictests { | 823 for _, tt := range panictests { |
820 s := Sprintf(tt.fmt, tt.in) | 824 s := Sprintf(tt.fmt, tt.in) |
821 if s != tt.out { | 825 if s != tt.out { |
822 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) | 826 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) |
823 } | 827 } |
824 } | 828 } |
825 } | 829 } |
826 | 830 |
827 // Test that erroneous String routine doesn't cause fatal recursion. | 831 // recurCount tests that erroneous String routine doesn't cause fatal recursion. |
828 var recurCount = 0 | 832 var recurCount = 0 |
829 | 833 |
830 type Recur struct { | 834 type Recur struct { |
831 i int | 835 i int |
832 failed *bool | 836 failed *bool |
833 } | 837 } |
834 | 838 |
835 func (r Recur) String() string { | 839 func (r Recur) String() string { |
836 if recurCount++; recurCount > 10 { | 840 if recurCount++; recurCount > 10 { |
837 *r.failed = true | 841 *r.failed = true |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 type A struct{} | 876 type A struct{} |
873 type B struct{} | 877 type B struct{} |
874 var a *A = nil | 878 var a *A = nil |
875 var b B = B{} | 879 var b B = B{} |
876 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) | 880 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) |
877 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil
>)" | 881 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil
>)" |
878 if got != expect { | 882 if got != expect { |
879 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) | 883 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) |
880 } | 884 } |
881 } | 885 } |
LEFT | RIGHT |