OSDN Git Service

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