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.
33 renamedUintptr
uintptr
36 renamedFloat32
float32
37 renamedFloat64
float64
38 renamedComplex64 complex64
39 renamedComplex128 complex128
42 func TestFmtInterface(t
*testing
.T
) {
45 s
:= Sprintf("%s", i1
)
47 t
.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s
, "abc")
51 const b32
uint32 = 1<<32 - 1
52 const b64
uint64 = 1<<64 - 1
54 var array
= [5]int{1, 2, 3, 4, 5}
55 var iarray
= [4]interface{}{1, "hello", 2.5, nil}
57 var islice
= iarray
[:]
68 func (i I
) String() string { return Sprintf("<%d>", int(i
)) }
82 func (f F
) Format(s State
, c rune
) {
83 Fprintf(s
, "<%c=F(%d)>", c
, int(f
))
88 func (g G
) GoString() string {
89 return Sprintf("GoString(%d)", int(g
))
93 F F
// a struct field that Formats
94 G G
// a struct field that GoStrings
101 // P is a type with a String method with pointer receiver for testing %p.
106 func (p
*P
) String() string {
110 var barray
= [5]renamedUint8
{1, 2, 3, 4, 5}
111 var bslice
= barray
[:]
113 type byteStringer
byte
115 func (byteStringer
) String() string { return "X" }
117 var byteStringerSlice
= []byteStringer
{97, 98, 99, 100}
119 type byteFormatter
byte
121 func (byteFormatter
) Format(f State
, _ rune
) {
125 var byteFormatterSlice
= []byteFormatter
{97, 98, 99, 100}
129 var fmtTests
= []struct {
134 {"%d", 12345, "12345"},
135 {"%v", 12345, "12345"},
136 {"%t", true, "true"},
139 {"%s", "abc", "abc"},
140 {"%q", "abc", `"abc"`},
141 {"%x", "abc", "616263"},
142 {"%x", "\xff\xf0\x0f\xff", "fff00fff"},
143 {"%X", "\xff\xf0\x0f\xff", "FFF00FFF"},
144 {"%x", "xyz", "78797a"},
145 {"%X", "xyz", "78797A"},
146 {"% x", "xyz", "78 79 7a"},
147 {"% X", "xyz", "78 79 7A"},
148 {"%#x", "xyz", "0x78797a"},
149 {"%#X", "xyz", "0X78797A"},
150 {"%# x", "xyz", "0x78 0x79 0x7a"},
151 {"%# X", "xyz", "0X78 0X79 0X7A"},
154 {"%s", []byte("abc"), "abc"},
155 {"%q", []byte("abc"), `"abc"`},
156 {"%x", []byte("abc"), "616263"},
157 {"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"},
158 {"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"},
159 {"%x", []byte("xyz"), "78797a"},
160 {"%X", []byte("xyz"), "78797A"},
161 {"% x", []byte("xyz"), "78 79 7a"},
162 {"% X", []byte("xyz"), "78 79 7A"},
163 {"%#x", []byte("xyz"), "0x78797a"},
164 {"%#X", []byte("xyz"), "0X78797A"},
165 {"%# x", []byte("xyz"), "0x78 0x79 0x7a"},
166 {"%# X", []byte("xyz"), "0X78 0X79 0X7A"},
169 {"%#q", `abc`, "`abc`"},
170 {"%#q", `"`, "`\"`"},
171 {"1 %#q", `\n`, "1 `\\n`"},
172 {"2 %#q", "\n", `2 "\n"`},
174 {"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`},
175 {"%q", "abc\xffdef", `"abc\xffdef"`},
176 {"%q", "\u263a", `"☺"`},
177 {"%+q", "\u263a", `"\u263a"`},
178 {"%q", "\U0010ffff", `"\U0010ffff"`},
180 // escaped characters
183 {"%q", '\n', `'\n'`},
184 {"%q", '\u0e00', `'\u0e00'`}, // not a printable rune.
185 {"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune.
186 {"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`},
187 {"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`},
189 {"%q", '\'', `'\''`},
190 {"%q", "\u263a", `"☺"`},
191 {"%+q", "\u263a", `"\u263a"`},
194 {"%5s", "abc", " abc"},
195 {"%2s", "\u263a", " ☺"},
196 {"%-5s", "abc", "abc "},
197 {"%-8q", "abc", `"abc" `},
198 {"%05s", "abc", "00abc"},
199 {"%08q", "abc", `000"abc"`},
200 {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
201 {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
202 {"%.5s", "日本語日本語", "日本語日本"},
203 {"%.5s", []byte("日本語日本語"), "日本語日本"},
204 {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
205 {"%.5x", "abcdefghijklmnopqrstuvwxyz", `6162636465`},
206 {"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
207 {"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), `6162636465`},
208 {"%.3q", "日本語日本語", `"日本語"`},
209 {"%.3q", []byte("日本語日本語"), `"日本語"`},
210 {"%.1q", "日本語", `"日"`},
211 {"%.1q", []byte("日本語"), `"日"`},
212 {"%.1x", "日本語", `e6`},
213 {"%.1X", []byte("日本語"), `E6`},
214 {"%10.1q", "日本語日本語", ` "日"`},
216 {"%5q", '\u2026', ` '…'`},
217 {"%10v", nil, " <nil>"},
218 {"%-10v", nil, "<nil> "},
221 {"%d", 12345, "12345"},
222 {"%d", -12345, "-12345"},
223 {"%10d", 12345, " 12345"},
224 {"%10d", -12345, " -12345"},
225 {"%+10d", 12345, " +12345"},
226 {"%010d", 12345, "0000012345"},
227 {"%010d", -12345, "-000012345"},
228 {"%-10d", 12345, "12345 "},
229 {"%010.3d", 1, " 001"},
230 {"%010.3d", -1, " -001"},
231 {"%+d", 12345, "+12345"},
232 {"%+d", -12345, "-12345"},
235 {"% d", 12345, " 12345"},
240 {"%U", 0x1, "U+0001"},
241 {"%U", uint(0x1), "U+0001"},
242 {"%.8U", 0x2, "U+00000002"},
243 {"%U", 0x1234, "U+1234"},
244 {"%U", 0x12345, "U+12345"},
245 {"%10.6U", 0xABC, " U+000ABC"},
246 {"%-10.6U", 0xABC, "U+000ABC "},
247 {"%U", '\n', `U+000A`},
248 {"%#U", '\n', `U+000A`},
249 {"%U", 'x', `U+0078`},
250 {"%#U", 'x', `U+0078 'x'`},
251 {"%U", '\u263a', `U+263A`},
252 {"%#U", '\u263a', `U+263A '☺'`},
255 {"%+.3e", 0.0, "+0.000e+00"},
256 {"%+.3e", 1.0, "+1.000e+00"},
257 {"%+.3f", -1.0, "-1.000"},
258 {"%+.3F", -1.0, "-1.000"},
259 {"%+.3F", float32(-1.0), "-1.000"},
260 {"%+07.2f", 1.0, "+001.00"},
261 {"%+07.2f", -1.0, "-001.00"},
262 {"%+10.2f", +1.0, " +1.00"},
263 {"%+10.2f", -1.0, " -1.00"},
264 {"% .3E", -1.0, "-1.000E+00"},
265 {"% .3e", 1.0, " 1.000e+00"},
266 {"%+.3g", 0.0, "+0"},
267 {"%+.3g", 1.0, "+1"},
268 {"%+.3g", -1.0, "-1"},
269 {"% .3g", -1.0, "-1"},
270 {"% .3g", 1.0, " 1"},
271 {"%b", float32(1.0), "8388608p-23"},
272 {"%b", 1.0, "4503599627370496p-52"},
275 {"%+.3e", 0i
, "(+0.000e+00+0.000e+00i)"},
276 {"%+.3f", 0i
, "(+0.000+0.000i)"},
277 {"%+.3g", 0i
, "(+0+0i)"},
278 {"%+.3e", 1 + 2i
, "(+1.000e+00+2.000e+00i)"},
279 {"%+.3f", 1 + 2i
, "(+1.000+2.000i)"},
280 {"%+.3g", 1 + 2i
, "(+1+2i)"},
281 {"%.3e", 0i
, "(0.000e+00+0.000e+00i)"},
282 {"%.3f", 0i
, "(0.000+0.000i)"},
283 {"%.3F", 0i
, "(0.000+0.000i)"},
284 {"%.3F", complex64(0i
), "(0.000+0.000i)"},
285 {"%.3g", 0i
, "(0+0i)"},
286 {"%.3e", 1 + 2i
, "(1.000e+00+2.000e+00i)"},
287 {"%.3f", 1 + 2i
, "(1.000+2.000i)"},
288 {"%.3g", 1 + 2i
, "(1+2i)"},
289 {"%.3e", -1 - 2i
, "(-1.000e+00-2.000e+00i)"},
290 {"%.3f", -1 - 2i
, "(-1.000-2.000i)"},
291 {"%.3g", -1 - 2i
, "(-1-2i)"},
292 {"% .3E", -1 - 2i
, "(-1.000E+00-2.000E+00i)"},
293 {"%+.3g", complex64(1 + 2i
), "(+1+2i)"},
294 {"%+.3g", complex128(1 + 2i
), "(+1+2i)"},
295 {"%b", complex64(1 + 2i
), "(8388608p-23+8388608p-22i)"},
296 {"%b", 1 + 2i
, "(4503599627370496p-52+4503599627370496p-51i)"},
299 {"", 2, "%!(EXTRA int=2)"},
300 {"%d", "hello", "%!d(string=hello)"},
302 // old test/fmt_test.go
303 {"%d", 1234, "1234"},
304 {"%d", -1234, "-1234"},
305 {"%d", uint(1234), "1234"},
306 {"%d", uint32(b32
), "4294967295"},
307 {"%d", uint64(b64
), "18446744073709551615"},
308 {"%o", 01234, "1234"},
309 {"%#o", 01234, "01234"},
310 {"%o", uint32(b32
), "37777777777"},
311 {"%o", uint64(b64
), "1777777777777777777777"},
312 {"%x", 0x1234abcd, "1234abcd"},
313 {"%#x", 0x1234abcd, "0x1234abcd"},
314 {"%x", b32
- 0x1234567, "fedcba98"},
315 {"%X", 0x1234abcd, "1234ABCD"},
316 {"%X", b32
- 0x1234567, "FEDCBA98"},
318 {"%x", b64
, "ffffffffffffffff"},
320 {"%b", b64
, "1111111111111111111111111111111111111111111111111111111111111111"},
322 {"%e", 1.0, "1.000000e+00"},
323 {"%e", 1234.5678e3
, "1.234568e+06"},
324 {"%e", 1234.5678e-8, "1.234568e-05"},
325 {"%e", -7.0, "-7.000000e+00"},
326 {"%e", -1e-9, "-1.000000e-09"},
327 {"%f", 1234.5678e3
, "1234567.800000"},
328 {"%f", 1234.5678e-8, "0.000012"},
329 {"%f", -7.0, "-7.000000"},
330 {"%f", -1e-9, "-0.000000"},
331 {"%g", 1234.5678e3
, "1.2345678e+06"},
332 {"%g", float32(1234.5678e3
), "1.2345678e+06"},
333 {"%g", 1234.5678e-8, "1.2345678e-05"},
335 {"%g", -1e-9, "-1e-09"},
336 {"%g", float32(-1e-9), "-1e-09"},
337 {"%E", 1.0, "1.000000E+00"},
338 {"%E", 1234.5678e3
, "1.234568E+06"},
339 {"%E", 1234.5678e-8, "1.234568E-05"},
340 {"%E", -7.0, "-7.000000E+00"},
341 {"%E", -1e-9, "-1.000000E-09"},
342 {"%G", 1234.5678e3
, "1.2345678E+06"},
343 {"%G", float32(1234.5678e3
), "1.2345678E+06"},
344 {"%G", 1234.5678e-8, "1.2345678E-05"},
346 {"%G", -1e-9, "-1E-09"},
347 {"%G", float32(-1e-9), "-1E-09"},
352 {"%20.8d", 1234, " 00001234"},
353 {"%20.8d", -1234, " -00001234"},
354 {"%20d", 1234, " 1234"},
355 {"%-20.8d", 1234, "00001234 "},
356 {"%-20.8d", -1234, "-00001234 "},
357 {"%-#20.8x", 0x1234abc, "0x01234abc "},
358 {"%-#20.8X", 0x1234abc, "0X01234ABC "},
359 {"%-#20.8o", 01234, "00001234 "},
360 {"%.20b", 7, "00000000000000000111"},
361 {"%20.5s", "qwertyuiop", " qwert"},
362 {"%.5s", "qwertyuiop", "qwert"},
363 {"%-20.5s", "qwertyuiop", "qwert "},
365 {"%-20c", 'x', "x "},
366 {"%20.6e", 1.2345e3
, " 1.234500e+03"},
367 {"%20.6e", 1.2345e-3, " 1.234500e-03"},
368 {"%20e", 1.2345e3
, " 1.234500e+03"},
369 {"%20e", 1.2345e-3, " 1.234500e-03"},
370 {"%20.8e", 1.2345e3
, " 1.23450000e+03"},
371 {"%20f", 1.23456789e3
, " 1234.567890"},
372 {"%20f", 1.23456789e-3, " 0.001235"},
373 {"%20f", 12345678901.23456789, " 12345678901.234568"},
374 {"%-20f", 1.23456789e3
, "1234.567890 "},
375 {"%20.8f", 1.23456789e3
, " 1234.56789000"},
376 {"%20.8f", 1.23456789e-3, " 0.00123457"},
377 {"%g", 1.23456789e3
, "1234.56789"},
378 {"%g", 1.23456789e-3, "0.00123456789"},
379 {"%g", 1.23456789e20
, "1.23456789e+20"},
380 {"%20e", math
.Inf(1), " +Inf"},
381 {"%-20f", math
.Inf(-1), "-Inf "},
382 {"%20g", math
.NaN(), " NaN"},
385 {"%v", array
, "[1 2 3 4 5]"},
386 {"%v", iarray
, "[1 hello 2.5 <nil>]"},
387 {"%v", barray
, "[1 2 3 4 5]"},
388 {"%v", &array
, "&[1 2 3 4 5]"},
389 {"%v", &iarray
, "&[1 hello 2.5 <nil>]"},
390 {"%v", &barray
, "&[1 2 3 4 5]"},
393 {"%v", slice
, "[1 2 3 4 5]"},
394 {"%v", islice
, "[1 hello 2.5 <nil>]"},
395 {"%v", bslice
, "[1 2 3 4 5]"},
396 {"%v", &slice
, "&[1 2 3 4 5]"},
397 {"%v", &islice
, "&[1 hello 2.5 <nil>]"},
398 {"%v", &bslice
, "&[1 2 3 4 5]"},
399 {"%v", []byte{1}, "[1]"},
400 {"%v", []byte{}, "[]"},
403 {"%v", 1 + 2i
, "(1+2i)"},
404 {"%v", complex64(1 + 2i
), "(1+2i)"},
405 {"%v", complex128(1 + 2i
), "(1+2i)"},
408 {"%v", A
{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
409 {"%+v", A
{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
411 // +v on structs with Stringable items
412 {"%+v", B
{1, 2}, `{I:<1> j:2}`},
413 {"%+v", C
{1, B
{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
415 // other formats on Stringable items
416 {"%s", I(23), `<23>`},
417 {"%q", I(23), `"<23>"`},
418 {"%x", I(23), `3c32333e`},
419 {"%#x", I(23), `0x3c32333e`},
420 {"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
421 {"%d", I(23), `23`}, // Stringer applies only to string formats.
424 {"%#v", A
{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
425 {"%#v", &b
, "(*uint8)(0xPTR)"},
426 {"%#v", TestFmtInterface
, "(func(*testing.T))(0xPTR)"},
427 {"%#v", make(chan int), "(chan int)(0xPTR)"},
428 {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
429 {"%#v", 1000000000, "1000000000"},
430 {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
431 {"%#v", map[string]B
{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
432 {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
433 {"%#v", SI
{}, `fmt_test.SI{I:interface {}(nil)}`},
434 {"%#v", []int(nil), `[]int(nil)`},
435 {"%#v", []int{}, `[]int{}`},
436 {"%#v", array
, `[5]int{1, 2, 3, 4, 5}`},
437 {"%#v", &array
, `&[5]int{1, 2, 3, 4, 5}`},
438 {"%#v", iarray
, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
439 {"%#v", &iarray
, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
440 {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
441 {"%#v", map[int]byte{}, `map[int]uint8{}`},
442 {"%#v", "foo", `"foo"`},
443 {"%#v", barray
, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
444 {"%#v", bslice
, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
445 {"%#v", []byte(nil), "[]byte(nil)"},
446 {"%#v", []int32(nil), "[]int32(nil)"},
448 // slices with other formats
449 {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
450 {"%x", []int{1, 2, 15}, `[1 2 f]`},
451 {"%d", []int{1, 2, 15}, `[1 2 15]`},
452 {"%d", []byte{1, 2, 15}, `[1 2 15]`},
453 {"%q", []string{"a", "b"}, `["a" "b"]`},
454 {"% 02x", []byte{1}, "01"},
455 {"% 02x", []byte{1, 2, 3}, "01 02 03"},
456 // Padding with byte slices.
457 {"%x", []byte{}, ""},
458 {"%02x", []byte{}, "00"},
459 {"% 02x", []byte{}, "00"},
460 {"%08x", []byte{0xab}, "000000ab"},
461 {"% 08x", []byte{0xab}, "000000ab"},
462 {"%08x", []byte{0xab, 0xcd}, "0000abcd"},
463 {"% 08x", []byte{0xab, 0xcd}, "000ab cd"},
464 {"%8x", []byte{0xab}, " ab"},
465 {"% 8x", []byte{0xab}, " ab"},
466 {"%8x", []byte{0xab, 0xcd}, " abcd"},
467 {"% 8x", []byte{0xab, 0xcd}, " ab cd"},
472 {"%08x", "\xab", "000000ab"},
473 {"% 08x", "\xab", "000000ab"},
474 {"%08x", "\xab\xcd", "0000abcd"},
475 {"% 08x", "\xab\xcd", "000ab cd"},
476 {"%8x", "\xab", " ab"},
477 {"% 8x", "\xab", " ab"},
478 {"%8x", "\xab\xcd", " abcd"},
479 {"% 8x", "\xab\xcd", " ab cd"},
482 {"%v", renamedBool(true), "true"},
483 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
484 {"%o", renamedInt(8), "10"},
485 {"%d", renamedInt8(-9), "-9"},
486 {"%v", renamedInt16(10), "10"},
487 {"%v", renamedInt32(-11), "-11"},
488 {"%X", renamedInt64(255), "FF"},
489 {"%v", renamedUint(13), "13"},
490 {"%o", renamedUint8(14), "16"},
491 {"%X", renamedUint16(15), "F"},
492 {"%d", renamedUint32(16), "16"},
493 {"%X", renamedUint64(17), "11"},
494 {"%o", renamedUintptr(18), "22"},
495 {"%x", renamedString("thing"), "7468696e67"},
496 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
497 {"%q", renamedBytes([]byte("hello")), `"hello"`},
498 {"%x", []renamedUint8
{'a', 'b', 'c'}, "616263"},
499 {"%s", []renamedUint8
{'h', 'e', 'l', 'l', 'o'}, "hello"},
500 {"%q", []renamedUint8
{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
501 {"%v", renamedFloat32(22), "22"},
502 {"%v", renamedFloat64(33), "33"},
503 {"%v", renamedComplex64(3 + 4i
), "(3+4i)"},
504 {"%v", renamedComplex128(4 - 3i
), "(4-3i)"},
507 {"%x", F(1), "<x=F(1)>"},
509 {"%+v", S
{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
512 {"%#v", G(6), "GoString(6)"},
513 {"%#v", S
{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
516 {"%T", (4 - 3i
), "complex128"},
517 {"%T", renamedComplex128(4 - 3i
), "fmt_test.renamedComplex128"},
518 {"%T", intVal
, "int"},
519 {"%6T", &intVal
, " *int"},
520 {"%10T", nil, " <nil>"},
521 {"%-10T", nil, "<nil> "},
524 {"p0=%p", new(int), "p0=0xPTR"},
525 {"p1=%s", &pValue
, "p1=String(p)"}, // String method...
526 {"p2=%p", &pValue
, "p2=0xPTR"}, // ... not called with %p
527 {"p3=%p", (*int)(nil), "p3=0x0"},
528 {"p4=%#p", new(int), "p4=PTR"},
530 // %p on non-pointers
531 {"%p", make(chan int), "0xPTR"},
532 {"%p", make(map[int]int), "0xPTR"},
533 {"%p", make([]int, 1), "0xPTR"},
534 {"%p", 27, "%!p(int=27)"}, // not a pointer at all
537 {"%q", (*int)(nil), "%!q(*int=<nil>)"},
538 {"%q", new(int), "%!q(*int=0xPTR)"},
540 // %v on pointers formats 0 as <nil>
541 {"%v", (*int)(nil), "<nil>"},
542 {"%v", new(int), "0xPTR"},
544 // %d etc. pointers use specified base.
545 {"%d", new(int), "PTR_d"},
546 {"%o", new(int), "PTR_o"},
547 {"%x", new(int), "PTR_x"},
549 // %d on Stringer should give integer if possible
550 {"%s", time
.Time
{}.Month(), "January"},
551 {"%d", time
.Time
{}.Month(), "1"},
554 {"%s %", "hello", "hello %!(NOVERB)"},
555 {"%s %.2", "hello", "hello %!(NOVERB)"},
556 {"%d", "hello", "%!d(string=hello)"},
557 {"no args", "hello", "no args%!(EXTRA string=hello)"},
558 {"%s", nil, "%!s(<nil>)"},
559 {"%T", nil, "<nil>"},
560 {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
561 {"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)%!(EXTRA int=0)"},
562 {"%184467440737095516170v", 0, "%!(NOVERB)%!(EXTRA int=0)"},
564 // The "<nil>" show up because maps are printed by
565 // first obtaining a list of keys and then looking up
566 // each key. Since NaNs can be map keys but cannot
567 // be fetched directly, the lookup fails and returns a
568 // zero reflect.Value, which formats as <nil>.
569 // This test is just to check that it shows the two NaNs at all.
570 {"%v", map[float64]int{math
.NaN(): 1, math
.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"},
572 // Used to crash because nByte didn't allow for a sign.
573 {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
576 {"%0100d", 1, zeroFill("", 100, "1")},
577 {"%0100d", -1, zeroFill("-", 99, "1")},
578 {"%0.100f", 1.0, zeroFill("1.", 100, "")},
579 {"%0.100f", -1.0, zeroFill("-1.", 100, "")},
581 // Used to panic: integer function didn't look at f.prec, f.unicode, f.width or sign.
582 {"%#.80x", 42, "0x0000000000000000000000000000000000000000000000000000000000000000000000000000002a"},
583 {"%.80U", 42, "U+0000000000000000000000000000000000000000000000000000000000000000000000000000002A"},
584 {"%#.80U", '日', "U+000000000000000000000000000000000000000000000000000000000000000000000000000065E5 '日'"},
585 {"%.65d", -44, "-00000000000000000000000000000000000000000000000000000000000000044"},
586 {"%+.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"},
587 {"% .65d", 44, " 00000000000000000000000000000000000000000000000000000000000000044"},
588 {"% +.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"},
590 // Comparison of padding rules with C printf.
609 for(i = 0; i < 9; i++) {
610 printf("%s: ", format[i]);
611 printf(format[i], 1.0);
613 printf(format[i], -1.0);
619 [%.2f]: [1.00] [-1.00]
620 [% .2f]: [ 1.00] [-1.00]
621 [%+.2f]: [+1.00] [-1.00]
622 [%7.2f]: [ 1.00] [ -1.00]
623 [% 7.2f]: [ 1.00] [ -1.00]
624 [%+7.2f]: [ +1.00] [ -1.00]
625 [%07.2f]: [0001.00] [-001.00]
626 [% 07.2f]: [ 001.00] [-001.00]
627 [%+07.2f]: [+001.00] [-001.00]
629 {"%.2f", 1.0, "1.00"},
630 {"%.2f", -1.0, "-1.00"},
631 {"% .2f", 1.0, " 1.00"},
632 {"% .2f", -1.0, "-1.00"},
633 {"%+.2f", 1.0, "+1.00"},
634 {"%+.2f", -1.0, "-1.00"},
635 {"%7.2f", 1.0, " 1.00"},
636 {"%7.2f", -1.0, " -1.00"},
637 {"% 7.2f", 1.0, " 1.00"},
638 {"% 7.2f", -1.0, " -1.00"},
639 {"%+7.2f", 1.0, " +1.00"},
640 {"%+7.2f", -1.0, " -1.00"},
641 {"%07.2f", 1.0, "0001.00"},
642 {"%07.2f", -1.0, "-001.00"},
643 {"% 07.2f", 1.0, " 001.00"},
644 {"% 07.2f", -1.0, "-001.00"},
645 {"%+07.2f", 1.0, "+001.00"},
646 {"%+07.2f", -1.0, "-001.00"},
648 // Complex numbers: exhaustively tested in TestComplexFormatting.
649 {"%7.2f", 1 + 2i
, "( 1.00 +2.00i)"},
650 {"%+07.2f", -1 - 2i
, "(-001.00-002.00i)"},
651 // Zero padding does not apply to infinities.
652 {"%020f", math
.Inf(-1), " -Inf"},
653 {"%020f", math
.Inf(+1), " +Inf"},
654 {"% 020f", math
.Inf(-1), " -Inf"},
655 {"% 020f", math
.Inf(+1), " Inf"},
656 {"%+020f", math
.Inf(-1), " -Inf"},
657 {"%+020f", math
.Inf(+1), " +Inf"},
658 {"%20f", -1.0, " -1.000000"},
659 // Make sure we can handle very large widths.
660 {"%0100f", -1.0, zeroFill("-", 99, "1.000000")},
662 // Complex fmt used to leave the plus flag set for future entries in the array
663 // causing +2+0i and +3+0i instead of 2+0i and 3+0i.
664 {"%v", []complex64
{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
665 {"%v", []complex128
{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
667 // Incomplete format specification caused crash.
668 {"%.", 3, "%!.(int=3)"},
670 // Used to panic with out-of-bounds for very large numeric representations.
671 // nByte is set to handle one bit per uint64 in %b format, with a negative number.
673 {"%#064x", 1, zeroFill("0x", 64, "1")},
674 {"%#064x", -1, zeroFill("-0x", 63, "1")},
675 {"%#064b", 1, zeroFill("", 64, "1")},
676 {"%#064b", -1, zeroFill("-", 63, "1")},
677 {"%#064o", 1, zeroFill("", 64, "1")},
678 {"%#064o", -1, zeroFill("-", 63, "1")},
679 {"%#064d", 1, zeroFill("", 64, "1")},
680 {"%#064d", -1, zeroFill("-", 63, "1")},
681 // Test that we handle the crossover above the size of uint64
682 {"%#072x", 1, zeroFill("0x", 72, "1")},
683 {"%#072x", -1, zeroFill("-0x", 71, "1")},
684 {"%#072b", 1, zeroFill("", 72, "1")},
685 {"%#072b", -1, zeroFill("-", 71, "1")},
686 {"%#072o", 1, zeroFill("", 72, "1")},
687 {"%#072o", -1, zeroFill("-", 71, "1")},
688 {"%#072d", 1, zeroFill("", 72, "1")},
689 {"%#072d", -1, zeroFill("-", 71, "1")},
691 // Padding for complex numbers. Has been bad, then fixed, then bad again.
692 {"%+10.2f", +104.66 + 440.51i
, "( +104.66 +440.51i)"},
693 {"%+10.2f", -104.66 + 440.51i
, "( -104.66 +440.51i)"},
694 {"%+10.2f", +104.66 - 440.51i
, "( +104.66 -440.51i)"},
695 {"%+10.2f", -104.66 - 440.51i
, "( -104.66 -440.51i)"},
696 {"%+010.2f", +104.66 + 440.51i
, "(+000104.66+000440.51i)"},
697 {"%+010.2f", -104.66 + 440.51i
, "(-000104.66+000440.51i)"},
698 {"%+010.2f", +104.66 - 440.51i
, "(+000104.66-000440.51i)"},
699 {"%+010.2f", -104.66 - 440.51i
, "(-000104.66-000440.51i)"},
701 // []T where type T is a byte with a Stringer method.
702 {"%v", byteStringerSlice
, "[X X X X]"},
703 {"%s", byteStringerSlice
, "abcd"},
704 {"%q", byteStringerSlice
, "\"abcd\""},
705 {"%x", byteStringerSlice
, "61626364"},
706 {"%#v", byteStringerSlice
, "[]fmt_test.byteStringer{0x61, 0x62, 0x63, 0x64}"},
708 // And the same for Formatter.
709 {"%v", byteFormatterSlice
, "[X X X X]"},
710 {"%s", byteFormatterSlice
, "abcd"},
711 {"%q", byteFormatterSlice
, "\"abcd\""},
712 {"%x", byteFormatterSlice
, "61626364"},
713 // This next case seems wrong, but the docs say the Formatter wins here.
714 {"%#v", byteFormatterSlice
, "[]fmt_test.byteFormatter{X, X, X, X}"},
716 // reflect.Value handled specially in Go 1.5, making it possible to
717 // see inside non-exported fields (which cannot be accessed with Interface()).
719 {"%v", reflect
.ValueOf(A
{}).Field(0).String(), "<int Value>"}, // Equivalent to the old way.
720 {"%v", reflect
.ValueOf(A
{}).Field(0), "0"}, // Sees inside the field.
722 // verbs apply to the extracted value too.
723 {"%s", reflect
.ValueOf("hello"), "hello"},
724 {"%q", reflect
.ValueOf("hello"), `"hello"`},
725 {"%#04x", reflect
.ValueOf(256), "0x0100"},
727 // invalid reflect.Value doesn't crash.
728 {"%v", reflect
.Value
{}, "<invalid reflect.Value>"},
731 // zeroFill generates zero-filled strings of the specified width. The length
732 // of the suffix (but not the prefix) is compensated for in the width calculation.
733 func zeroFill(prefix
string, width
int, suffix
string) string {
734 return prefix
+ strings
.Repeat("0", width
-len(suffix
)) + suffix
737 func TestSprintf(t
*testing
.T
) {
738 for _
, tt
:= range fmtTests
{
739 s
:= Sprintf(tt
.fmt
, tt
.val
)
740 if i
:= strings
.Index(tt
.out
, "PTR"); i
>= 0 {
742 chars
:= "0123456789abcdefABCDEF"
744 case strings
.HasPrefix(tt
.out
[i
:], "PTR_d"):
747 case strings
.HasPrefix(tt
.out
[i
:], "PTR_o"):
750 case strings
.HasPrefix(tt
.out
[i
:], "PTR_x"):
754 for ; j
< len(s
); j
++ {
756 if !strings
.ContainsRune(chars
, rune(c
)) {
760 s
= s
[0:i
] + pattern
+ s
[j
:]
763 if _
, ok
:= tt
.val
.(string); ok
{
764 // Don't requote the already-quoted strings.
765 // It's too confusing to read the errors.
766 t
.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt
.fmt
, tt
.val
, s
, tt
.out
)
768 t
.Errorf("Sprintf(%q, %v) = %q want %q", tt
.fmt
, tt
.val
, s
, tt
.out
)
774 // TestComplexFormatting checks that a complex always formats to the same
775 // thing as if done by hand with two singleton prints.
776 func TestComplexFormatting(t
*testing
.T
) {
777 var yesNo
= []bool{true, false}
778 var values
= []float64{1, 0, -1, math
.Inf(1), math
.Inf(-1), math
.NaN()}
779 for _
, plus
:= range yesNo
{
780 for _
, zero
:= range yesNo
{
781 for _
, space
:= range yesNo
{
782 for _
, char
:= range "fFeEgG" {
794 realFmt
+= string(char
)
795 // Imaginary part always has a sign, so force + and ignore space.
802 imagFmt
+= string(char
)
803 for _
, realValue
:= range values
{
804 for _
, imagValue
:= range values
{
805 one
:= Sprintf(realFmt
, complex(realValue
, imagValue
))
806 two
:= Sprintf("("+realFmt
+imagFmt
+"i)", realValue
, imagValue
)
818 type SE
[]interface{} // slice of empty; notational compactness.
820 var reorderTests
= []struct {
825 {"%[1]d", SE
{1}, "1"},
826 {"%[2]d", SE
{2, 1}, "1"},
827 {"%[2]d %[1]d", SE
{1, 2}, "2 1"},
828 {"%[2]*[1]d", SE
{2, 5}, " 2"},
829 {"%6.2f", SE
{12.0}, " 12.00"}, // Explicit version of next line.
830 {"%[3]*.[2]*[1]f", SE
{12.0, 2, 6}, " 12.00"},
831 {"%[1]*.[2]*[3]f", SE
{6, 2, 12.0}, " 12.00"},
832 {"%10f", SE
{12.0}, " 12.000000"},
833 {"%[1]*[3]f", SE
{10, 99, 12.0}, " 12.000000"},
834 {"%.6f", SE
{12.0}, "12.000000"}, // Explicit version of next line.
835 {"%.[1]*[3]f", SE
{6, 99, 12.0}, "12.000000"},
836 {"%6.f", SE
{12.0}, " 12"}, // // Explicit version of next line; empty precision means zero.
837 {"%[1]*.[3]f", SE
{6, 3, 12.0}, " 12"},
838 // An actual use! Print the same arguments twice.
839 {"%d %d %d %#[1]o %#o %#o", SE
{11, 12, 13}, "11 12 13 013 014 015"},
842 {"%[d", SE
{2, 1}, "%!d(BADINDEX)"},
843 {"%]d", SE
{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
844 {"%[]d", SE
{2, 1}, "%!d(BADINDEX)"},
845 {"%[-3]d", SE
{2, 1}, "%!d(BADINDEX)"},
846 {"%[99]d", SE
{2, 1}, "%!d(BADINDEX)"},
847 {"%[3]", SE
{2, 1}, "%!(NOVERB)"},
848 {"%[1].2d", SE
{5, 6}, "%!d(BADINDEX)"},
849 {"%[1]2d", SE
{2, 1}, "%!d(BADINDEX)"},
850 {"%3.[2]d", SE
{7}, "%!d(BADINDEX)"},
851 {"%.[2]d", SE
{7}, "%!d(BADINDEX)"},
852 {"%d %d %d %#[1]o %#o %#o %#o", SE
{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
853 {"%[5]d %[2]d %d", SE
{1, 2, 3}, "%!d(BADINDEX) 2 3"},
854 {"%d %[3]d %d", SE
{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
855 {"%.[]", SE
{}, "%!](BADINDEX)"}, // Issue 10675
856 {"%.-3d", SE
{42}, "%!-(int=42)3d"}, // TODO: Should this set return better error messages?
857 {"%2147483648d", SE
{42}, "%!(NOVERB)%!(EXTRA int=42)"},
858 {"%-2147483648d", SE
{42}, "%!(NOVERB)%!(EXTRA int=42)"},
859 {"%.2147483648d", SE
{42}, "%!(NOVERB)%!(EXTRA int=42)"},
862 func TestReorder(t
*testing
.T
) {
863 for _
, tt
:= range reorderTests
{
864 s
:= Sprintf(tt
.fmt
, tt
.val
...)
866 t
.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt
.fmt
, tt
.val
, s
, tt
.out
)
872 func BenchmarkSprintfEmpty(b
*testing
.B
) {
873 b
.RunParallel(func(pb
*testing
.PB
) {
880 func BenchmarkSprintfString(b
*testing
.B
) {
881 b
.RunParallel(func(pb
*testing
.PB
) {
883 Sprintf("%s", "hello")
888 func BenchmarkSprintfInt(b
*testing
.B
) {
889 b
.RunParallel(func(pb
*testing
.PB
) {
896 func BenchmarkSprintfIntInt(b
*testing
.B
) {
897 b
.RunParallel(func(pb
*testing
.PB
) {
899 Sprintf("%d %d", 5, 6)
904 func BenchmarkSprintfPrefixedInt(b
*testing
.B
) {
905 b
.RunParallel(func(pb
*testing
.PB
) {
907 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
912 func BenchmarkSprintfFloat(b
*testing
.B
) {
913 b
.RunParallel(func(pb
*testing
.PB
) {
915 Sprintf("%g", 5.23184)
920 func BenchmarkManyArgs(b
*testing
.B
) {
921 b
.RunParallel(func(pb
*testing
.PB
) {
925 Fprintf(&buf
, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
930 func BenchmarkFprintInt(b
*testing
.B
) {
932 for i
:= 0; i
< b
.N
; i
++ {
938 func BenchmarkFprintfBytes(b
*testing
.B
) {
939 data
:= []byte(string("0123456789"))
941 for i
:= 0; i
< b
.N
; i
++ {
943 Fprintf(&buf
, "%s", data
)
947 func BenchmarkFprintIntNoAlloc(b
*testing
.B
) {
948 var x
interface{} = 123456
950 for i
:= 0; i
< b
.N
; i
++ {
956 var mallocBuf bytes
.Buffer
957 var mallocPointer
*int // A pointer so we know the interface value won't allocate.
959 // gccgo numbers are different because gccgo does not have escape
961 var mallocTest
= []struct {
966 {5, `Sprintf("")`, func() { Sprintf("") }},
967 {5, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
968 {5, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
969 {5, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
970 {5, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
971 {20, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1?
972 {5, `Fprintf(buf, "%s")`, func() { mallocBuf
.Reset(); Fprintf(&mallocBuf
, "%s", "hello") }},
973 // If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
974 {5, `Fprintf(buf, "%x %x %x")`, func() {
976 Fprintf(&mallocBuf
, "%x %x %x", mallocPointer
, mallocPointer
, mallocPointer
)
982 func TestCountMallocs(t
*testing
.T
) {
984 case testing
.Short():
985 t
.Skip("skipping malloc count in short mode")
986 case runtime
.GOMAXPROCS(0) > 1:
987 t
.Skip("skipping; GOMAXPROCS>1")
989 t
.Skip("skipping malloc count under race detector")
991 for _
, mt
:= range mallocTest
{
992 mallocs
:= testing
.AllocsPerRun(100, mt
.fn
)
993 if got
, max
:= mallocs
, float64(mt
.count
); got
> max
{
994 t
.Errorf("%s: got %v allocs, want <=%v", mt
.desc
, got
, max
)
999 type flagPrinter
struct{}
1001 func (flagPrinter
) Format(f State
, c rune
) {
1003 for i
:= 0; i
< 128; i
++ {
1008 if w
, ok
:= f
.Width(); ok
{
1009 s
+= Sprintf("%d", w
)
1011 if p
, ok
:= f
.Precision(); ok
{
1012 s
+= Sprintf(".%d", p
)
1015 io
.WriteString(f
, "["+s
+"]")
1018 var flagtests
= []struct {
1028 {"%1.2a", "[%1.2a]"},
1029 {"%-1.2a", "[%-1.2a]"},
1030 {"%+1.2a", "[%+1.2a]"},
1031 {"%-+1.2a", "[%+-1.2a]"},
1032 {"%-+1.2abc", "[%+-1.2a]bc"},
1033 {"%-1.2abc", "[%-1.2a]bc"},
1036 func TestFlagParser(t
*testing
.T
) {
1037 var flagprinter flagPrinter
1038 for _
, tt
:= range flagtests
{
1039 s
:= Sprintf(tt
.in
, &flagprinter
)
1041 t
.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt
.in
, s
, tt
.out
)
1046 func TestStructPrinter(t
*testing
.T
) {
1056 var tests
= []struct {
1060 {"%v", "{abc def 123}"},
1061 {"%+v", "{a:abc b:def c:123}"},
1062 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`},
1064 for _
, tt
:= range tests
{
1065 out
:= Sprintf(tt
.fmt
, s
)
1067 t
.Errorf("Sprintf(%q, s) = %#q, want %#q", tt
.fmt
, out
, tt
.out
)
1069 // The same but with a pointer.
1070 out
= Sprintf(tt
.fmt
, &s
)
1071 if out
!= "&"+tt
.out
{
1072 t
.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt
.fmt
, out
, "&"+tt
.out
)
1077 func TestSlicePrinter(t
*testing
.T
) {
1081 t
.Errorf("empty slice printed as %q not %q", s
, "[]")
1083 slice
= []int{1, 2, 3}
1086 t
.Errorf("slice: got %q expected %q", s
, "[1 2 3]")
1089 if s
!= "&[1 2 3]" {
1090 t
.Errorf("&slice: got %q expected %q", s
, "&[1 2 3]")
1094 // presentInMap checks map printing using substrings so we don't depend on the
1096 func presentInMap(s
string, a
[]string, t
*testing
.T
) {
1097 for i
:= 0; i
< len(a
); i
++ {
1098 loc
:= strings
.Index(s
, a
[i
])
1100 t
.Errorf("map print: expected to find %q in %q", a
[i
], s
)
1102 // make sure the match ends here
1104 if loc
>= len(s
) ||
(s
[loc
] != ' ' && s
[loc
] != ']') {
1105 t
.Errorf("map print: %q not properly terminated in %q", a
[i
], s
)
1110 func TestMapPrinter(t
*testing
.T
) {
1111 m0
:= make(map[int]string)
1114 t
.Errorf("empty map printed as %q not %q", s
, "map[]")
1116 m1
:= map[int]string{1: "one", 2: "two", 3: "three"}
1117 a
:= []string{"1:one", "2:two", "3:three"}
1118 presentInMap(Sprintf("%v", m1
), a
, t
)
1119 presentInMap(Sprint(m1
), a
, t
)
1120 // Pointer to map prints the same but with initial &.
1121 if !strings
.HasPrefix(Sprint(&m1
), "&") {
1122 t
.Errorf("no initial & for address of map")
1124 presentInMap(Sprintf("%v", &m1
), a
, t
)
1125 presentInMap(Sprint(&m1
), a
, t
)
1128 func TestEmptyMap(t
*testing
.T
) {
1129 const emptyMapStr
= "map[]"
1130 var m
map[string]int
1132 if s
!= emptyMapStr
{
1133 t
.Errorf("nil map printed as %q not %q", s
, emptyMapStr
)
1135 m
= make(map[string]int)
1137 if s
!= emptyMapStr
{
1138 t
.Errorf("empty map printed as %q not %q", s
, emptyMapStr
)
1142 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
1143 // right places, that is, between arg pairs in which neither is a string.
1144 func TestBlank(t
*testing
.T
) {
1145 got
:= Sprint("<", 1, ">:", 1, 2, 3, "!")
1146 expect
:= "<1>:1 2 3!"
1148 t
.Errorf("got %q expected %q", got
, expect
)
1152 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
1153 // the right places, that is, between all arg pairs.
1154 func TestBlankln(t
*testing
.T
) {
1155 got
:= Sprintln("<", 1, ">:", 1, 2, 3, "!")
1156 expect
:= "< 1 >: 1 2 3 !\n"
1158 t
.Errorf("got %q expected %q", got
, expect
)
1162 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
1163 func TestFormatterPrintln(t
*testing
.T
) {
1165 expect
:= "<v=F(1)>\n"
1166 s
:= Sprint(f
, "\n")
1168 t
.Errorf("Sprint wrong with Formatter: expected %q got %q", expect
, s
)
1172 t
.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect
, s
)
1174 s
= Sprintf("%v\n", f
)
1176 t
.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect
, s
)
1180 func args(a
...interface{}) []interface{} { return a
}
1182 var startests
= []struct {
1187 {"%*d", args(4, 42), " 42"},
1188 {"%-*d", args(4, 42), "42 "},
1189 {"%*d", args(-4, 42), "42 "},
1190 {"%-*d", args(-4, 42), "42 "},
1191 {"%.*d", args(4, 42), "0042"},
1192 {"%*.*d", args(8, 4, 42), " 0042"},
1193 {"%0*d", args(4, 42), "0042"},
1194 // Some non-int types for width. (Issue 10732).
1195 {"%0*d", args(uint(4), 42), "0042"},
1196 {"%0*d", args(uint64(4), 42), "0042"},
1197 {"%0*d", args('\x04', 42), "0042"},
1198 {"%0*d", args(uintptr(4), 42), "0042"},
1201 {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
1202 {"%*d", args(int(1e7
), 42), "%!(BADWIDTH)42"},
1203 {"%*d", args(int(-1e7
), 42), "%!(BADWIDTH)42"},
1204 {"%.*d", args(nil, 42), "%!(BADPREC)42"},
1205 {"%.*d", args(-1, 42), "%!(BADPREC)42"},
1206 {"%.*d", args(int(1e7
), 42), "%!(BADPREC)42"},
1207 {"%.*d", args(uint(1e7
), 42), "%!(BADPREC)42"},
1208 {"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"}, // Huge negative (-inf).
1209 {"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"}, // Small negative (-1).
1210 {"%*d", args(5, "foo"), "%!d(string= foo)"},
1211 {"%*% %d", args(20, 5), "% 5"},
1212 {"%*", args(4), "%!(NOVERB)"},
1215 func TestWidthAndPrecision(t
*testing
.T
) {
1216 for i
, tt
:= range startests
{
1217 s
:= Sprintf(tt
.fmt
, tt
.in
...)
1219 t
.Errorf("#%d: %q: got %q expected %q", i
, tt
.fmt
, s
, tt
.out
)
1224 // Panic is a type that panics in String.
1230 func (p Panic
) GoString() string {
1235 func (p Panic
) String() string {
1239 // PanicF is a type that panics in Format.
1240 type PanicF
struct {
1245 func (p PanicF
) Format(f State
, c rune
) {
1249 var panictests
= []struct {
1255 {"%s", (*Panic
)(nil), "<nil>"}, // nil pointer special case
1256 {"%s", Panic
{io
.ErrUnexpectedEOF
}, "%!s(PANIC=unexpected EOF)"},
1257 {"%s", Panic
{3}, "%!s(PANIC=3)"},
1259 {"%#v", (*Panic
)(nil), "<nil>"}, // nil pointer special case
1260 {"%#v", Panic
{io
.ErrUnexpectedEOF
}, "%!v(PANIC=unexpected EOF)"},
1261 {"%#v", Panic
{3}, "%!v(PANIC=3)"},
1263 {"%s", (*PanicF
)(nil), "<nil>"}, // nil pointer special case
1264 {"%s", PanicF
{io
.ErrUnexpectedEOF
}, "%!s(PANIC=unexpected EOF)"},
1265 {"%s", PanicF
{3}, "%!s(PANIC=3)"},
1268 func TestPanics(t
*testing
.T
) {
1269 for i
, tt
:= range panictests
{
1270 s
:= Sprintf(tt
.fmt
, tt
.in
)
1272 t
.Errorf("%d: %q: got %q expected %q", i
, tt
.fmt
, s
, tt
.out
)
1277 // recurCount tests that erroneous String routine doesn't cause fatal recursion.
1285 func (r
*Recur
) String() string {
1286 if recurCount
++; recurCount
> 10 {
1290 // This will call badVerb. Before the fix, that would cause us to recur into
1291 // this routine to print %!p(value). Now we don't call the user's method
1293 return Sprintf("recur@%p value: %d", r
, r
.i
)
1296 func TestBadVerbRecursion(t
*testing
.T
) {
1298 r
:= &Recur
{3, &failed
}
1299 Sprintf("recur@%p value: %d\n", &r
, r
.i
)
1301 t
.Error("fail with pointer")
1304 r
= &Recur
{4, &failed
}
1305 Sprintf("recur@%p, value: %d\n", r
, r
.i
)
1307 t
.Error("fail with value")
1311 func TestIsSpace(t
*testing
.T
) {
1312 // This tests the internal isSpace function.
1313 // IsSpace = isSpace is defined in export_test.go.
1314 for i
:= rune(0); i
<= unicode
.MaxRune
; i
++ {
1315 if IsSpace(i
) != unicode
.IsSpace(i
) {
1316 t
.Errorf("isSpace(%U) = %v, want %v", i
, IsSpace(i
), unicode
.IsSpace(i
))
1321 func TestNilDoesNotBecomeTyped(t
*testing
.T
) {
1326 got
:= Sprintf("%s %s %s %s %s", nil, a
, nil, b
, nil) // go vet should complain about this line.
1327 const expect
= "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
1329 t
.Errorf("expected:\n\t%q\ngot:\n\t%q", expect
, got
)
1333 var formatterFlagTests
= []struct {
1338 // scalar values with the (unused by fmt) 'a' verb.
1339 {"%a", flagPrinter
{}, "[%a]"},
1340 {"%-a", flagPrinter
{}, "[%-a]"},
1341 {"%+a", flagPrinter
{}, "[%+a]"},
1342 {"%#a", flagPrinter
{}, "[%#a]"},
1343 {"% a", flagPrinter
{}, "[% a]"},
1344 {"%0a", flagPrinter
{}, "[%0a]"},
1345 {"%1.2a", flagPrinter
{}, "[%1.2a]"},
1346 {"%-1.2a", flagPrinter
{}, "[%-1.2a]"},
1347 {"%+1.2a", flagPrinter
{}, "[%+1.2a]"},
1348 {"%-+1.2a", flagPrinter
{}, "[%+-1.2a]"},
1349 {"%-+1.2abc", flagPrinter
{}, "[%+-1.2a]bc"},
1350 {"%-1.2abc", flagPrinter
{}, "[%-1.2a]bc"},
1352 // composite values with the 'a' verb
1353 {"%a", [1]flagPrinter
{}, "[[%a]]"},
1354 {"%-a", [1]flagPrinter
{}, "[[%-a]]"},
1355 {"%+a", [1]flagPrinter
{}, "[[%+a]]"},
1356 {"%#a", [1]flagPrinter
{}, "[[%#a]]"},
1357 {"% a", [1]flagPrinter
{}, "[[% a]]"},
1358 {"%0a", [1]flagPrinter
{}, "[[%0a]]"},
1359 {"%1.2a", [1]flagPrinter
{}, "[[%1.2a]]"},
1360 {"%-1.2a", [1]flagPrinter
{}, "[[%-1.2a]]"},
1361 {"%+1.2a", [1]flagPrinter
{}, "[[%+1.2a]]"},
1362 {"%-+1.2a", [1]flagPrinter
{}, "[[%+-1.2a]]"},
1363 {"%-+1.2abc", [1]flagPrinter
{}, "[[%+-1.2a]]bc"},
1364 {"%-1.2abc", [1]flagPrinter
{}, "[[%-1.2a]]bc"},
1366 // simple values with the 'v' verb
1367 {"%v", flagPrinter
{}, "[%v]"},
1368 {"%-v", flagPrinter
{}, "[%-v]"},
1369 {"%+v", flagPrinter
{}, "[%+v]"},
1370 {"%#v", flagPrinter
{}, "[%#v]"},
1371 {"% v", flagPrinter
{}, "[% v]"},
1372 {"%0v", flagPrinter
{}, "[%0v]"},
1373 {"%1.2v", flagPrinter
{}, "[%1.2v]"},
1374 {"%-1.2v", flagPrinter
{}, "[%-1.2v]"},
1375 {"%+1.2v", flagPrinter
{}, "[%+1.2v]"},
1376 {"%-+1.2v", flagPrinter
{}, "[%+-1.2v]"},
1377 {"%-+1.2vbc", flagPrinter
{}, "[%+-1.2v]bc"},
1378 {"%-1.2vbc", flagPrinter
{}, "[%-1.2v]bc"},
1380 // composite values with the 'v' verb.
1381 {"%v", [1]flagPrinter
{}, "[[%v]]"},
1382 {"%-v", [1]flagPrinter
{}, "[[%-v]]"},
1383 {"%+v", [1]flagPrinter
{}, "[[%+v]]"},
1384 {"%#v", [1]flagPrinter
{}, "[1]fmt_test.flagPrinter{[%#v]}"},
1385 {"% v", [1]flagPrinter
{}, "[[% v]]"},
1386 {"%0v", [1]flagPrinter
{}, "[[%0v]]"},
1387 {"%1.2v", [1]flagPrinter
{}, "[[%1.2v]]"},
1388 {"%-1.2v", [1]flagPrinter
{}, "[[%-1.2v]]"},
1389 {"%+1.2v", [1]flagPrinter
{}, "[[%+1.2v]]"},
1390 {"%-+1.2v", [1]flagPrinter
{}, "[[%+-1.2v]]"},
1391 {"%-+1.2vbc", [1]flagPrinter
{}, "[[%+-1.2v]]bc"},
1392 {"%-1.2vbc", [1]flagPrinter
{}, "[[%-1.2v]]bc"},
1395 func TestFormatterFlags(t
*testing
.T
) {
1396 for _
, tt
:= range formatterFlagTests
{
1397 s
:= Sprintf(tt
.in
, tt
.val
)
1399 t
.Errorf("Sprintf(%q, %T) = %q, want %q", tt
.in
, tt
.val
, s
, tt
.out
)