OSDN Git Service

1b02f52baa9fcd2121f987f278c40c1667ee9d70
[pf3gnuchains/gcc-fork.git] / libgo / go / fmt / fmt_test.go
1 // Copyright 2009 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.
4
5 package fmt_test
6
7 import (
8         "bytes"
9         . "fmt"
10         "io"
11         "math"
12         "runtime" // for the malloc count test only
13         "strings"
14         "testing"
15         "time"
16 )
17
18 type (
19         renamedBool       bool
20         renamedInt        int
21         renamedInt8       int8
22         renamedInt16      int16
23         renamedInt32      int32
24         renamedInt64      int64
25         renamedUint       uint
26         renamedUint8      uint8
27         renamedUint16     uint16
28         renamedUint32     uint32
29         renamedUint64     uint64
30         renamedUintptr    uintptr
31         renamedString     string
32         renamedBytes      []byte
33         renamedFloat32    float32
34         renamedFloat64    float64
35         renamedComplex64  complex64
36         renamedComplex128 complex128
37 )
38
39 func TestFmtInterface(t *testing.T) {
40         var i1 interface{}
41         i1 = "abc"
42         s := Sprintf("%s", i1)
43         if s != "abc" {
44                 t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
45         }
46 }
47
48 const b32 uint32 = 1<<32 - 1
49 const b64 uint64 = 1<<64 - 1
50
51 var array = [5]int{1, 2, 3, 4, 5}
52 var iarray = [4]interface{}{1, "hello", 2.5, nil}
53 var slice = array[:]
54 var islice = iarray[:]
55
56 type A struct {
57         i int
58         j uint
59         s string
60         x []int
61 }
62
63 type I int
64
65 func (i I) String() string { return Sprintf("<%d>", int(i)) }
66
67 type B struct {
68         I I
69         j int
70 }
71
72 type C struct {
73         i int
74         B
75 }
76
77 type F int
78
79 func (f F) Format(s State, c rune) {
80         Fprintf(s, "<%c=F(%d)>", c, int(f))
81 }
82
83 type G int
84
85 func (g G) GoString() string {
86         return Sprintf("GoString(%d)", int(g))
87 }
88
89 type S struct {
90         F F // a struct field that Formats
91         G G // a struct field that GoStrings
92 }
93
94 type SI struct {
95         I interface{}
96 }
97
98 // A type with a String method with pointer receiver for testing %p
99 type P int
100
101 var pValue P
102
103 func (p *P) String() string {
104         return "String(p)"
105 }
106
107 var b byte
108
109 var fmttests = []struct {
110         fmt string
111         val interface{}
112         out string
113 }{
114         {"%d", 12345, "12345"},
115         {"%v", 12345, "12345"},
116         {"%t", true, "true"},
117
118         // basic string
119         {"%s", "abc", "abc"},
120         {"%x", "abc", "616263"},
121         {"%x", "xyz", "78797a"},
122         {"%X", "xyz", "78797A"},
123         {"%q", "abc", `"abc"`},
124
125         // basic bytes
126         {"%s", []byte("abc"), "abc"},
127         {"%x", []byte("abc"), "616263"},
128         {"% x", []byte("abc\xff"), "61 62 63 ff"},
129         {"% X", []byte("abc\xff"), "61 62 63 FF"},
130         {"%x", []byte("xyz"), "78797a"},
131         {"%X", []byte("xyz"), "78797A"},
132         {"%q", []byte("abc"), `"abc"`},
133
134         // escaped strings
135         {"%#q", `abc`, "`abc`"},
136         {"%#q", `"`, "`\"`"},
137         {"1 %#q", `\n`, "1 `\\n`"},
138         {"2 %#q", "\n", `2 "\n"`},
139         {"%q", `"`, `"\""`},
140         {"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`},
141         {"%q", "abc\xffdef", `"abc\xffdef"`},
142         {"%q", "\u263a", `"☺"`},
143         {"%+q", "\u263a", `"\u263a"`},
144         {"%q", "\U0010ffff", `"\U0010ffff"`},
145
146         // escaped characters
147         {"%q", 'x', `'x'`},
148         {"%q", 0, `'\x00'`},
149         {"%q", '\n', `'\n'`},
150         {"%q", '\u0e00', `'\u0e00'`},         // not a printable rune.
151         {"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune.
152         {"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`},
153         {"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`},
154         {"%q", '"', `'"'`},
155         {"%q", '\'', `'\''`},
156         {"%q", "\u263a", `"☺"`},
157         {"%+q", "\u263a", `"\u263a"`},
158
159         // width
160         {"%5s", "abc", "  abc"},
161         {"%2s", "\u263a", " ☺"},
162         {"%-5s", "abc", "abc  "},
163         {"%-8q", "abc", `"abc"   `},
164         {"%05s", "abc", "00abc"},
165         {"%08q", "abc", `000"abc"`},
166         {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
167         {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
168         {"%.5s", "日本語日本語", "日本語日本"},
169         {"%.5s", []byte("日本語日本語"), "日本語日本"},
170         {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
171         {"%.3q", "日本語日本語", `"日本語"`},
172         {"%.3q", []byte("日本語日本語"), `"日本語"`},
173         {"%10.1q", "日本語日本語", `       "日"`},
174
175         // integers
176         {"%d", 12345, "12345"},
177         {"%d", -12345, "-12345"},
178         {"%10d", 12345, "     12345"},
179         {"%10d", -12345, "    -12345"},
180         {"%+10d", 12345, "    +12345"},
181         {"%010d", 12345, "0000012345"},
182         {"%010d", -12345, "-000012345"},
183         {"%-10d", 12345, "12345     "},
184         {"%010.3d", 1, "       001"},
185         {"%010.3d", -1, "      -001"},
186         {"%+d", 12345, "+12345"},
187         {"%+d", -12345, "-12345"},
188         {"%+d", 0, "+0"},
189         {"% d", 0, " 0"},
190         {"% d", 12345, " 12345"},
191         {"%.0d", 0, ""},
192         {"%.d", 0, ""},
193
194         // unicode format
195         {"%U", 0x1, "U+0001"},
196         {"%U", uint(0x1), "U+0001"},
197         {"%.8U", 0x2, "U+00000002"},
198         {"%U", 0x1234, "U+1234"},
199         {"%U", 0x12345, "U+12345"},
200         {"%10.6U", 0xABC, "  U+000ABC"},
201         {"%-10.6U", 0xABC, "U+000ABC  "},
202         {"%U", '\n', `U+000A`},
203         {"%#U", '\n', `U+000A`},
204         {"%U", 'x', `U+0078`},
205         {"%#U", 'x', `U+0078 'x'`},
206         {"%U", '\u263a', `U+263A`},
207         {"%#U", '\u263a', `U+263A '☺'`},
208
209         // floats
210         {"%+.3e", 0.0, "+0.000e+00"},
211         {"%+.3e", 1.0, "+1.000e+00"},
212         {"%+.3f", -1.0, "-1.000"},
213         {"% .3E", -1.0, "-1.000E+00"},
214         {"% .3e", 1.0, " 1.000e+00"},
215         {"%+.3g", 0.0, "+0"},
216         {"%+.3g", 1.0, "+1"},
217         {"%+.3g", -1.0, "-1"},
218         {"% .3g", -1.0, "-1"},
219         {"% .3g", 1.0, " 1"},
220
221         // complex values
222         {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
223         {"%+.3f", 0i, "(+0.000+0.000i)"},
224         {"%+.3g", 0i, "(+0+0i)"},
225         {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
226         {"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
227         {"%+.3g", 1 + 2i, "(+1+2i)"},
228         {"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
229         {"%.3f", 0i, "(0.000+0.000i)"},
230         {"%.3g", 0i, "(0+0i)"},
231         {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
232         {"%.3f", 1 + 2i, "(1.000+2.000i)"},
233         {"%.3g", 1 + 2i, "(1+2i)"},
234         {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
235         {"%.3f", -1 - 2i, "(-1.000-2.000i)"},
236         {"%.3g", -1 - 2i, "(-1-2i)"},
237         {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
238         {"%+.3g", complex64(1 + 2i), "(+1+2i)"},
239         {"%+.3g", complex128(1 + 2i), "(+1+2i)"},
240
241         // erroneous formats
242         {"", 2, "%!(EXTRA int=2)"},
243         {"%d", "hello", "%!d(string=hello)"},
244
245         // old test/fmt_test.go
246         {"%d", 1234, "1234"},
247         {"%d", -1234, "-1234"},
248         {"%d", uint(1234), "1234"},
249         {"%d", uint32(b32), "4294967295"},
250         {"%d", uint64(b64), "18446744073709551615"},
251         {"%o", 01234, "1234"},
252         {"%#o", 01234, "01234"},
253         {"%o", uint32(b32), "37777777777"},
254         {"%o", uint64(b64), "1777777777777777777777"},
255         {"%x", 0x1234abcd, "1234abcd"},
256         {"%#x", 0x1234abcd, "0x1234abcd"},
257         {"%x", b32 - 0x1234567, "fedcba98"},
258         {"%X", 0x1234abcd, "1234ABCD"},
259         {"%X", b32 - 0x1234567, "FEDCBA98"},
260         {"%#X", 0, "0X0"},
261         {"%x", b64, "ffffffffffffffff"},
262         {"%b", 7, "111"},
263         {"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"},
264         {"%b", -6, "-110"},
265         {"%e", 1.0, "1.000000e+00"},
266         {"%e", 1234.5678e3, "1.234568e+06"},
267         {"%e", 1234.5678e-8, "1.234568e-05"},
268         {"%e", -7.0, "-7.000000e+00"},
269         {"%e", -1e-9, "-1.000000e-09"},
270         {"%f", 1234.5678e3, "1234567.800000"},
271         {"%f", 1234.5678e-8, "0.000012"},
272         {"%f", -7.0, "-7.000000"},
273         {"%f", -1e-9, "-0.000000"},
274         {"%g", 1234.5678e3, "1.2345678e+06"},
275         {"%g", float32(1234.5678e3), "1.2345678e+06"},
276         {"%g", 1234.5678e-8, "1.2345678e-05"},
277         {"%g", -7.0, "-7"},
278         {"%g", -1e-9, "-1e-09"},
279         {"%g", float32(-1e-9), "-1e-09"},
280         {"%E", 1.0, "1.000000E+00"},
281         {"%E", 1234.5678e3, "1.234568E+06"},
282         {"%E", 1234.5678e-8, "1.234568E-05"},
283         {"%E", -7.0, "-7.000000E+00"},
284         {"%E", -1e-9, "-1.000000E-09"},
285         {"%G", 1234.5678e3, "1.2345678E+06"},
286         {"%G", float32(1234.5678e3), "1.2345678E+06"},
287         {"%G", 1234.5678e-8, "1.2345678E-05"},
288         {"%G", -7.0, "-7"},
289         {"%G", -1e-9, "-1E-09"},
290         {"%G", float32(-1e-9), "-1E-09"},
291         {"%c", 'x', "x"},
292         {"%c", 0xe4, "ä"},
293         {"%c", 0x672c, "本"},
294         {"%c", '日', "日"},
295         {"%20.8d", 1234, "            00001234"},
296         {"%20.8d", -1234, "           -00001234"},
297         {"%20d", 1234, "                1234"},
298         {"%-20.8d", 1234, "00001234            "},
299         {"%-20.8d", -1234, "-00001234           "},
300         {"%-#20.8x", 0x1234abc, "0x01234abc          "},
301         {"%-#20.8X", 0x1234abc, "0X01234ABC          "},
302         {"%-#20.8o", 01234, "00001234            "},
303         {"%.20b", 7, "00000000000000000111"},
304         {"%20.5s", "qwertyuiop", "               qwert"},
305         {"%.5s", "qwertyuiop", "qwert"},
306         {"%-20.5s", "qwertyuiop", "qwert               "},
307         {"%20c", 'x', "                   x"},
308         {"%-20c", 'x', "x                   "},
309         {"%20.6e", 1.2345e3, "        1.234500e+03"},
310         {"%20.6e", 1.2345e-3, "        1.234500e-03"},
311         {"%20e", 1.2345e3, "        1.234500e+03"},
312         {"%20e", 1.2345e-3, "        1.234500e-03"},
313         {"%20.8e", 1.2345e3, "      1.23450000e+03"},
314         {"%20f", 1.23456789e3, "         1234.567890"},
315         {"%20f", 1.23456789e-3, "            0.001235"},
316         {"%20f", 12345678901.23456789, "  12345678901.234568"},
317         {"%-20f", 1.23456789e3, "1234.567890         "},
318         {"%20.8f", 1.23456789e3, "       1234.56789000"},
319         {"%20.8f", 1.23456789e-3, "          0.00123457"},
320         {"%g", 1.23456789e3, "1234.56789"},
321         {"%g", 1.23456789e-3, "0.00123456789"},
322         {"%g", 1.23456789e20, "1.23456789e+20"},
323         {"%20e", math.Inf(1), "                +Inf"},
324         {"%-20f", math.Inf(-1), "-Inf                "},
325         {"%20g", math.NaN(), "                 NaN"},
326
327         // arrays
328         {"%v", array, "[1 2 3 4 5]"},
329         {"%v", iarray, "[1 hello 2.5 <nil>]"},
330         {"%v", &array, "&[1 2 3 4 5]"},
331         {"%v", &iarray, "&[1 hello 2.5 <nil>]"},
332
333         // slices
334         {"%v", slice, "[1 2 3 4 5]"},
335         {"%v", islice, "[1 hello 2.5 <nil>]"},
336         {"%v", &slice, "&[1 2 3 4 5]"},
337         {"%v", &islice, "&[1 hello 2.5 <nil>]"},
338
339         // complexes with %v
340         {"%v", 1 + 2i, "(1+2i)"},
341         {"%v", complex64(1 + 2i), "(1+2i)"},
342         {"%v", complex128(1 + 2i), "(1+2i)"},
343
344         // structs
345         {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
346         {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
347
348         // +v on structs with Stringable items
349         {"%+v", B{1, 2}, `{I:<1> j:2}`},
350         {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
351
352         // q on Stringable items
353         {"%s", I(23), `<23>`},
354         {"%q", I(23), `"<23>"`},
355         {"%x", I(23), `3c32333e`},
356         {"%d", I(23), `23`}, // Stringer applies only to string formats.
357
358         // go syntax
359         {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
360         {"%#v", &b, "(*uint8)(0xPTR)"},
361         {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
362         {"%#v", make(chan int), "(chan int)(0xPTR)"},
363         {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
364         {"%#v", 1000000000, "1000000000"},
365         {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
366         {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
367         {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
368         {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
369         {"%#v", []int(nil), `[]int(nil)`},
370         {"%#v", []int{}, `[]int{}`},
371         {"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
372         {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
373         {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
374         {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
375         {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
376         {"%#v", map[int]byte{}, `map[int]uint8{}`},
377
378         // slices with other formats
379         {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
380         {"%x", []int{1, 2, 15}, `[1 2 f]`},
381         {"%d", []int{1, 2, 15}, `[1 2 15]`},
382         {"%d", []byte{1, 2, 15}, `[1 2 15]`},
383         {"%q", []string{"a", "b"}, `["a" "b"]`},
384
385         // renamings
386         {"%v", renamedBool(true), "true"},
387         {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
388         {"%o", renamedInt(8), "10"},
389         {"%d", renamedInt8(-9), "-9"},
390         {"%v", renamedInt16(10), "10"},
391         {"%v", renamedInt32(-11), "-11"},
392         {"%X", renamedInt64(255), "FF"},
393         {"%v", renamedUint(13), "13"},
394         {"%o", renamedUint8(14), "16"},
395         {"%X", renamedUint16(15), "F"},
396         {"%d", renamedUint32(16), "16"},
397         {"%X", renamedUint64(17), "11"},
398         {"%o", renamedUintptr(18), "22"},
399         {"%x", renamedString("thing"), "7468696e67"},
400         {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
401         {"%q", renamedBytes([]byte("hello")), `"hello"`},
402         {"%v", renamedFloat32(22), "22"},
403         {"%v", renamedFloat64(33), "33"},
404         {"%v", renamedComplex64(3 + 4i), "(3+4i)"},
405         {"%v", renamedComplex128(4 - 3i), "(4-3i)"},
406
407         // Formatter
408         {"%x", F(1), "<x=F(1)>"},
409         {"%x", G(2), "2"},
410         {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
411
412         // GoStringer
413         {"%#v", G(6), "GoString(6)"},
414         {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
415
416         // %T
417         {"%T", (4 - 3i), "complex128"},
418         {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
419         {"%T", intVal, "int"},
420         {"%6T", &intVal, "  *int"},
421
422         // %p
423         {"p0=%p", new(int), "p0=0xPTR"},
424         {"p1=%s", &pValue, "p1=String(p)"}, // String method...
425         {"p2=%p", &pValue, "p2=0xPTR"},     // ... not called with %p
426         {"p4=%#p", new(int), "p4=PTR"},
427
428         // %p on non-pointers
429         {"%p", make(chan int), "0xPTR"},
430         {"%p", make(map[int]int), "0xPTR"},
431         {"%p", make([]int, 1), "0xPTR"},
432         {"%p", 27, "%!p(int=27)"}, // not a pointer at all
433
434         // %d on Stringer should give integer if possible
435         {"%s", time.Time{}.Month(), "January"},
436         {"%d", time.Time{}.Month(), "1"},
437
438         // erroneous things
439         {"%s %", "hello", "hello %!(NOVERB)"},
440         {"%s %.2", "hello", "hello %!(NOVERB)"},
441         {"%d", "hello", "%!d(string=hello)"},
442         {"no args", "hello", "no args%!(EXTRA string=hello)"},
443         {"%s", nil, "%!s(<nil>)"},
444         {"%T", nil, "<nil>"},
445         {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
446
447         // The "<nil>" show up because maps are printed by
448         // first obtaining a list of keys and then looking up
449         // each key.  Since NaNs can be map keys but cannot
450         // be fetched directly, the lookup fails and returns a
451         // zero reflect.Value, which formats as <nil>.
452         // This test is just to check that it shows the two NaNs at all.
453         {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"},
454 }
455
456 func TestSprintf(t *testing.T) {
457         for _, tt := range fmttests {
458                 s := Sprintf(tt.fmt, tt.val)
459                 if i := strings.Index(tt.out, "PTR"); i >= 0 {
460                         j := i
461                         for ; j < len(s); j++ {
462                                 c := s[j]
463                                 if (c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F') {
464                                         break
465                                 }
466                         }
467                         s = s[0:i] + "PTR" + s[j:]
468                 }
469                 if s != tt.out {
470                         if _, ok := tt.val.(string); ok {
471                                 // Don't requote the already-quoted strings.
472                                 // It's too confusing to read the errors.
473                                 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
474                         } else {
475                                 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
476                         }
477                 }
478         }
479 }
480
481 func BenchmarkSprintfEmpty(b *testing.B) {
482         for i := 0; i < b.N; i++ {
483                 Sprintf("")
484         }
485 }
486
487 func BenchmarkSprintfString(b *testing.B) {
488         for i := 0; i < b.N; i++ {
489                 Sprintf("%s", "hello")
490         }
491 }
492
493 func BenchmarkSprintfInt(b *testing.B) {
494         for i := 0; i < b.N; i++ {
495                 Sprintf("%d", 5)
496         }
497 }
498
499 func BenchmarkSprintfIntInt(b *testing.B) {
500         for i := 0; i < b.N; i++ {
501                 Sprintf("%d %d", 5, 6)
502         }
503 }
504
505 func BenchmarkSprintfPrefixedInt(b *testing.B) {
506         for i := 0; i < b.N; i++ {
507                 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
508         }
509 }
510
511 func BenchmarkSprintfFloat(b *testing.B) {
512         for i := 0; i < b.N; i++ {
513                 Sprintf("%g", 5.23184)
514         }
515 }
516
517 var mallocBuf bytes.Buffer
518
519 // gccgo numbers are different because gccgo does not have escape
520 // analysis yet.
521 var mallocTest = []struct {
522         count int
523         desc  string
524         fn    func()
525 }{
526         {5, `Sprintf("")`, func() { Sprintf("") }},
527         {5, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
528         {5, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
529         {5, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
530         {5, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
531         // For %g we use a float32, not float64, to guarantee passing the argument
532         // does not need to allocate memory to store the result in a pointer-sized word.
533         {20, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }},
534         {5, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }},
535         {5, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
536 }
537
538 var _ bytes.Buffer
539
540 func TestCountMallocs(t *testing.T) {
541         for _, mt := range mallocTest {
542                 const N = 100
543                 memstats := new(runtime.MemStats)
544                 runtime.ReadMemStats(memstats)
545                 mallocs := 0 - memstats.Mallocs
546                 for i := 0; i < N; i++ {
547                         mt.fn()
548                 }
549                 runtime.ReadMemStats(memstats)
550                 mallocs += memstats.Mallocs
551                 if mallocs/N > uint64(mt.count) {
552                         t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
553                 }
554         }
555 }
556
557 type flagPrinter struct{}
558
559 func (*flagPrinter) Format(f State, c rune) {
560         s := "%"
561         for i := 0; i < 128; i++ {
562                 if f.Flag(i) {
563                         s += string(i)
564                 }
565         }
566         if w, ok := f.Width(); ok {
567                 s += Sprintf("%d", w)
568         }
569         if p, ok := f.Precision(); ok {
570                 s += Sprintf(".%d", p)
571         }
572         s += string(c)
573         io.WriteString(f, "["+s+"]")
574 }
575
576 var flagtests = []struct {
577         in  string
578         out string
579 }{
580         {"%a", "[%a]"},
581         {"%-a", "[%-a]"},
582         {"%+a", "[%+a]"},
583         {"%#a", "[%#a]"},
584         {"% a", "[% a]"},
585         {"%0a", "[%0a]"},
586         {"%1.2a", "[%1.2a]"},
587         {"%-1.2a", "[%-1.2a]"},
588         {"%+1.2a", "[%+1.2a]"},
589         {"%-+1.2a", "[%+-1.2a]"},
590         {"%-+1.2abc", "[%+-1.2a]bc"},
591         {"%-1.2abc", "[%-1.2a]bc"},
592 }
593
594 func TestFlagParser(t *testing.T) {
595         var flagprinter flagPrinter
596         for _, tt := range flagtests {
597                 s := Sprintf(tt.in, &flagprinter)
598                 if s != tt.out {
599                         t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
600                 }
601         }
602 }
603
604 func TestStructPrinter(t *testing.T) {
605         var s struct {
606                 a string
607                 b string
608                 c int
609         }
610         s.a = "abc"
611         s.b = "def"
612         s.c = 123
613         var tests = []struct {
614                 fmt string
615                 out string
616         }{
617                 {"%v", "{abc def 123}"},
618                 {"%+v", "{a:abc b:def c:123}"},
619         }
620         for _, tt := range tests {
621                 out := Sprintf(tt.fmt, s)
622                 if out != tt.out {
623                         t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out)
624                 }
625         }
626 }
627
628 // Check map printing using substrings so we don't depend on the print order.
629 func presentInMap(s string, a []string, t *testing.T) {
630         for i := 0; i < len(a); i++ {
631                 loc := strings.Index(s, a[i])
632                 if loc < 0 {
633                         t.Errorf("map print: expected to find %q in %q", a[i], s)
634                 }
635                 // make sure the match ends here
636                 loc += len(a[i])
637                 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
638                         t.Errorf("map print: %q not properly terminated in %q", a[i], s)
639                 }
640         }
641 }
642
643 func TestMapPrinter(t *testing.T) {
644         m0 := make(map[int]string)
645         s := Sprint(m0)
646         if s != "map[]" {
647                 t.Errorf("empty map printed as %q not %q", s, "map[]")
648         }
649         m1 := map[int]string{1: "one", 2: "two", 3: "three"}
650         a := []string{"1:one", "2:two", "3:three"}
651         presentInMap(Sprintf("%v", m1), a, t)
652         presentInMap(Sprint(m1), a, t)
653 }
654
655 func TestEmptyMap(t *testing.T) {
656         const emptyMapStr = "map[]"
657         var m map[string]int
658         s := Sprint(m)
659         if s != emptyMapStr {
660                 t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
661         }
662         m = make(map[string]int)
663         s = Sprint(m)
664         if s != emptyMapStr {
665                 t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
666         }
667 }
668
669 // Check that Sprint (and hence Print, Fprint) puts spaces in the right places,
670 // that is, between arg pairs in which neither is a string.
671 func TestBlank(t *testing.T) {
672         got := Sprint("<", 1, ">:", 1, 2, 3, "!")
673         expect := "<1>:1 2 3!"
674         if got != expect {
675                 t.Errorf("got %q expected %q", got, expect)
676         }
677 }
678
679 // Check that Sprintln (and hence Println, Fprintln) puts spaces in the right places,
680 // that is, between all arg pairs.
681 func TestBlankln(t *testing.T) {
682         got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
683         expect := "< 1 >: 1 2 3 !\n"
684         if got != expect {
685                 t.Errorf("got %q expected %q", got, expect)
686         }
687 }
688
689 // Check Formatter with Sprint, Sprintln, Sprintf
690 func TestFormatterPrintln(t *testing.T) {
691         f := F(1)
692         expect := "<v=F(1)>\n"
693         s := Sprint(f, "\n")
694         if s != expect {
695                 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
696         }
697         s = Sprintln(f)
698         if s != expect {
699                 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
700         }
701         s = Sprintf("%v\n", f)
702         if s != expect {
703                 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
704         }
705 }
706
707 func args(a ...interface{}) []interface{} { return a }
708
709 var startests = []struct {
710         fmt string
711         in  []interface{}
712         out string
713 }{
714         {"%*d", args(4, 42), "  42"},
715         {"%.*d", args(4, 42), "0042"},
716         {"%*.*d", args(8, 4, 42), "    0042"},
717         {"%0*d", args(4, 42), "0042"},
718         {"%-*d", args(4, 42), "42  "},
719
720         // erroneous
721         {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
722         {"%.*d", args(nil, 42), "%!(BADPREC)42"},
723         {"%*d", args(5, "foo"), "%!d(string=  foo)"},
724         {"%*% %d", args(20, 5), "% 5"},
725         {"%*", args(4), "%!(NOVERB)"},
726         {"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
727 }
728
729 func TestWidthAndPrecision(t *testing.T) {
730         for _, tt := range startests {
731                 s := Sprintf(tt.fmt, tt.in...)
732                 if s != tt.out {
733                         t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
734                 }
735         }
736 }
737
738 // A type that panics in String.
739 type Panic struct {
740         message interface{}
741 }
742
743 // Value receiver.
744 func (p Panic) GoString() string {
745         panic(p.message)
746 }
747
748 // Value receiver.
749 func (p Panic) String() string {
750         panic(p.message)
751 }
752
753 // A type that panics in Format.
754 type PanicF struct {
755         message interface{}
756 }
757
758 // Value receiver.
759 func (p PanicF) Format(f State, c rune) {
760         panic(p.message)
761 }
762
763 var panictests = []struct {
764         fmt string
765         in  interface{}
766         out string
767 }{
768         // String
769         {"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case
770         {"%s", Panic{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"},
771         {"%s", Panic{3}, "%s(PANIC=3)"},
772         // GoString
773         {"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case
774         {"%#v", Panic{io.ErrUnexpectedEOF}, "%v(PANIC=unexpected EOF)"},
775         {"%#v", Panic{3}, "%v(PANIC=3)"},
776         // Format
777         {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
778         {"%s", PanicF{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"},
779         {"%s", PanicF{3}, "%s(PANIC=3)"},
780 }
781
782 func TestPanics(t *testing.T) {
783         for _, tt := range panictests {
784                 s := Sprintf(tt.fmt, tt.in)
785                 if s != tt.out {
786                         t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
787                 }
788         }
789 }
790
791 // Test that erroneous String routine doesn't cause fatal recursion.
792 var recurCount = 0
793
794 type Recur struct {
795         i      int
796         failed *bool
797 }
798
799 func (r Recur) String() string {
800         if recurCount++; recurCount > 10 {
801                 *r.failed = true
802                 return "FAIL"
803         }
804         // This will call badVerb. Before the fix, that would cause us to recur into
805         // this routine to print %!p(value). Now we don't call the user's method
806         // during an error.
807         return Sprintf("recur@%p value: %d", r, r.i)
808 }
809
810 func TestBadVerbRecursion(t *testing.T) {
811         failed := false
812         r := Recur{3, &failed}
813         Sprintf("recur@%p value: %d\n", &r, r.i)
814         if failed {
815                 t.Error("fail with pointer")
816         }
817         failed = false
818         r = Recur{4, &failed}
819         Sprintf("recur@%p, value: %d\n", r, r.i)
820         if failed {
821                 t.Error("fail with value")
822         }
823 }