OSDN Git Service

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