OSDN Git Service

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