2017-03-02 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / go / fmt / fmt_test.go
blobce00456c7bafd24db2342a0dc7e0cbe9f2b276ac
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.
5 package fmt_test
7 import (
8 "bytes"
9 . "fmt"
10 "internal/race"
11 "io"
12 "math"
13 "reflect"
14 "runtime"
15 "strings"
16 "testing"
17 "time"
18 "unicode"
21 type (
22 renamedBool bool
23 renamedInt int
24 renamedInt8 int8
25 renamedInt16 int16
26 renamedInt32 int32
27 renamedInt64 int64
28 renamedUint uint
29 renamedUint8 uint8
30 renamedUint16 uint16
31 renamedUint32 uint32
32 renamedUint64 uint64
33 renamedUintptr uintptr
34 renamedString string
35 renamedBytes []byte
36 renamedFloat32 float32
37 renamedFloat64 float64
38 renamedComplex64 complex64
39 renamedComplex128 complex128
42 func TestFmtInterface(t *testing.T) {
43 var i1 interface{}
44 i1 = "abc"
45 s := Sprintf("%s", i1)
46 if s != "abc" {
47 t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
51 var (
52 NaN = math.NaN()
53 posInf = math.Inf(1)
54 negInf = math.Inf(-1)
56 intVar = 0
58 array = [5]int{1, 2, 3, 4, 5}
59 iarray = [4]interface{}{1, "hello", 2.5, nil}
60 slice = array[:]
61 islice = iarray[:]
64 type A struct {
65 i int
66 j uint
67 s string
68 x []int
71 type I int
73 func (i I) String() string { return Sprintf("<%d>", int(i)) }
75 type B struct {
76 I I
77 j int
80 type C struct {
81 i int
85 type F int
87 func (f F) Format(s State, c rune) {
88 Fprintf(s, "<%c=F(%d)>", c, int(f))
91 type G int
93 func (g G) GoString() string {
94 return Sprintf("GoString(%d)", int(g))
97 type S struct {
98 F F // a struct field that Formats
99 G G // a struct field that GoStrings
102 type SI struct {
103 I interface{}
106 // P is a type with a String method with pointer receiver for testing %p.
107 type P int
109 var pValue P
111 func (p *P) String() string {
112 return "String(p)"
115 var barray = [5]renamedUint8{1, 2, 3, 4, 5}
116 var bslice = barray[:]
118 type byteStringer byte
120 func (byteStringer) String() string {
121 return "X"
124 var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'}
126 type byteFormatter byte
128 func (byteFormatter) Format(f State, _ rune) {
129 Fprint(f, "X")
132 var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
134 var fmtTests = []struct {
135 fmt string
136 val interface{}
137 out string
139 {"%d", 12345, "12345"},
140 {"%v", 12345, "12345"},
141 {"%t", true, "true"},
143 // basic string
144 {"%s", "abc", "abc"},
145 {"%q", "abc", `"abc"`},
146 {"%x", "abc", "616263"},
147 {"%x", "\xff\xf0\x0f\xff", "fff00fff"},
148 {"%X", "\xff\xf0\x0f\xff", "FFF00FFF"},
149 {"%x", "", ""},
150 {"% x", "", ""},
151 {"%#x", "", ""},
152 {"%# x", "", ""},
153 {"%x", "xyz", "78797a"},
154 {"%X", "xyz", "78797A"},
155 {"% x", "xyz", "78 79 7a"},
156 {"% X", "xyz", "78 79 7A"},
157 {"%#x", "xyz", "0x78797a"},
158 {"%#X", "xyz", "0X78797A"},
159 {"%# x", "xyz", "0x78 0x79 0x7a"},
160 {"%# X", "xyz", "0X78 0X79 0X7A"},
162 // basic bytes
163 {"%s", []byte("abc"), "abc"},
164 {"%s", [3]byte{'a', 'b', 'c'}, "abc"},
165 {"%s", &[3]byte{'a', 'b', 'c'}, "&abc"},
166 {"%q", []byte("abc"), `"abc"`},
167 {"%x", []byte("abc"), "616263"},
168 {"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"},
169 {"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"},
170 {"%x", []byte(""), ""},
171 {"% x", []byte(""), ""},
172 {"%#x", []byte(""), ""},
173 {"%# x", []byte(""), ""},
174 {"%x", []byte("xyz"), "78797a"},
175 {"%X", []byte("xyz"), "78797A"},
176 {"% x", []byte("xyz"), "78 79 7a"},
177 {"% X", []byte("xyz"), "78 79 7A"},
178 {"%#x", []byte("xyz"), "0x78797a"},
179 {"%#X", []byte("xyz"), "0X78797A"},
180 {"%# x", []byte("xyz"), "0x78 0x79 0x7a"},
181 {"%# X", []byte("xyz"), "0X78 0X79 0X7A"},
183 // escaped strings
184 {"%q", "", `""`},
185 {"%#q", "", "``"},
186 {"%q", "\"", `"\""`},
187 {"%#q", "\"", "`\"`"},
188 {"%q", "`", `"` + "`" + `"`},
189 {"%#q", "`", `"` + "`" + `"`},
190 {"%q", "\n", `"\n"`},
191 {"%#q", "\n", `"\n"`},
192 {"%q", `\n`, `"\\n"`},
193 {"%#q", `\n`, "`\\n`"},
194 {"%q", "abc", `"abc"`},
195 {"%#q", "abc", "`abc`"},
196 {"%q", "日本語", `"日本語"`},
197 {"%+q", "日本語", `"\u65e5\u672c\u8a9e"`},
198 {"%#q", "日本語", "`日本語`"},
199 {"%#+q", "日本語", "`日本語`"},
200 {"%q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
201 {"%+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
202 {"%#q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
203 {"%#+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
204 {"%q", "☺", `"☺"`},
205 {"% q", "☺", `"☺"`}, // The space modifier should have no effect.
206 {"%+q", "☺", `"\u263a"`},
207 {"%#q", "☺", "`☺`"},
208 {"%#+q", "☺", "`☺`"},
209 {"%10q", "⌘", ` "⌘"`},
210 {"%+10q", "⌘", ` "\u2318"`},
211 {"%-10q", "⌘", `"⌘" `},
212 {"%+-10q", "⌘", `"\u2318" `},
213 {"%010q", "⌘", `0000000"⌘"`},
214 {"%+010q", "⌘", `00"\u2318"`},
215 {"%-010q", "⌘", `"⌘" `}, // 0 has no effect when - is present.
216 {"%+-010q", "⌘", `"\u2318" `},
217 {"%#8q", "\n", ` "\n"`},
218 {"%#+8q", "\r", ` "\r"`},
219 {"%#-8q", "\t", "` ` "},
220 {"%#+-8q", "\b", `"\b" `},
221 {"%q", "abc\xffdef", `"abc\xffdef"`},
222 {"%+q", "abc\xffdef", `"abc\xffdef"`},
223 {"%#q", "abc\xffdef", `"abc\xffdef"`},
224 {"%#+q", "abc\xffdef", `"abc\xffdef"`},
225 // Runes that are not printable.
226 {"%q", "\U0010ffff", `"\U0010ffff"`},
227 {"%+q", "\U0010ffff", `"\U0010ffff"`},
228 {"%#q", "\U0010ffff", "`􏿿`"},
229 {"%#+q", "\U0010ffff", "`􏿿`"},
230 // Runes that are not valid.
231 {"%q", string(0x110000), `"�"`},
232 {"%+q", string(0x110000), `"\ufffd"`},
233 {"%#q", string(0x110000), "`�`"},
234 {"%#+q", string(0x110000), "`�`"},
236 // characters
237 {"%c", uint('x'), "x"},
238 {"%c", 0xe4, "ä"},
239 {"%c", 0x672c, "本"},
240 {"%c", '日', "日"},
241 {"%.0c", '⌘', "⌘"}, // Specifying precision should have no effect.
242 {"%3c", '⌘', " ⌘"},
243 {"%-3c", '⌘', "⌘ "},
244 // Runes that are not printable.
245 {"%c", '\U00000e00', "\u0e00"},
246 {"%c", '\U0010ffff', "\U0010ffff"},
247 // Runes that are not valid.
248 {"%c", -1, "�"},
249 {"%c", 0xDC80, "�"},
250 {"%c", rune(0x110000), "�"},
251 {"%c", int64(0xFFFFFFFFF), "�"},
252 {"%c", uint64(0xFFFFFFFFF), "�"},
254 // escaped characters
255 {"%q", uint(0), `'\x00'`},
256 {"%+q", uint(0), `'\x00'`},
257 {"%q", '"', `'"'`},
258 {"%+q", '"', `'"'`},
259 {"%q", '\'', `'\''`},
260 {"%+q", '\'', `'\''`},
261 {"%q", '`', "'`'"},
262 {"%+q", '`', "'`'"},
263 {"%q", 'x', `'x'`},
264 {"%+q", 'x', `'x'`},
265 {"%q", 'ÿ', `'ÿ'`},
266 {"%+q", 'ÿ', `'\u00ff'`},
267 {"%q", '\n', `'\n'`},
268 {"%+q", '\n', `'\n'`},
269 {"%q", '☺', `'☺'`},
270 {"%+q", '☺', `'\u263a'`},
271 {"% q", '☺', `'☺'`}, // The space modifier should have no effect.
272 {"%.0q", '☺', `'☺'`}, // Specifying precision should have no effect.
273 {"%10q", '⌘', ` '⌘'`},
274 {"%+10q", '⌘', ` '\u2318'`},
275 {"%-10q", '⌘', `'⌘' `},
276 {"%+-10q", '⌘', `'\u2318' `},
277 {"%010q", '⌘', `0000000'⌘'`},
278 {"%+010q", '⌘', `00'\u2318'`},
279 {"%-010q", '⌘', `'⌘' `}, // 0 has no effect when - is present.
280 {"%+-010q", '⌘', `'\u2318' `},
281 // Runes that are not printable.
282 {"%q", '\U00000e00', `'\u0e00'`},
283 {"%q", '\U0010ffff', `'\U0010ffff'`},
284 // Runes that are not valid.
285 {"%q", int32(-1), "%!q(int32=-1)"},
286 {"%q", 0xDC80, `'�'`},
287 {"%q", rune(0x110000), "%!q(int32=1114112)"},
288 {"%q", int64(0xFFFFFFFFF), "%!q(int64=68719476735)"},
289 {"%q", uint64(0xFFFFFFFFF), "%!q(uint64=68719476735)"},
291 // width
292 {"%5s", "abc", " abc"},
293 {"%2s", "\u263a", " ☺"},
294 {"%-5s", "abc", "abc "},
295 {"%-8q", "abc", `"abc" `},
296 {"%05s", "abc", "00abc"},
297 {"%08q", "abc", `000"abc"`},
298 {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
299 {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
300 {"%.0s", "日本語日本語", ""},
301 {"%.5s", "日本語日本語", "日本語日本"},
302 {"%.10s", "日本語日本語", "日本語日本語"},
303 {"%.5s", []byte("日本語日本語"), "日本語日本"},
304 {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
305 {"%.5x", "abcdefghijklmnopqrstuvwxyz", "6162636465"},
306 {"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
307 {"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), "6162636465"},
308 {"%.3q", "日本語日本語", `"日本語"`},
309 {"%.3q", []byte("日本語日本語"), `"日本語"`},
310 {"%.1q", "日本語", `"日"`},
311 {"%.1q", []byte("日本語"), `"日"`},
312 {"%.1x", "日本語", "e6"},
313 {"%.1X", []byte("日本語"), "E6"},
314 {"%10.1q", "日本語日本語", ` "日"`},
315 {"%10v", nil, " <nil>"},
316 {"%-10v", nil, "<nil> "},
318 // integers
319 {"%d", uint(12345), "12345"},
320 {"%d", int(-12345), "-12345"},
321 {"%d", ^uint8(0), "255"},
322 {"%d", ^uint16(0), "65535"},
323 {"%d", ^uint32(0), "4294967295"},
324 {"%d", ^uint64(0), "18446744073709551615"},
325 {"%d", int8(-1 << 7), "-128"},
326 {"%d", int16(-1 << 15), "-32768"},
327 {"%d", int32(-1 << 31), "-2147483648"},
328 {"%d", int64(-1 << 63), "-9223372036854775808"},
329 {"%.d", 0, ""},
330 {"%.0d", 0, ""},
331 {"%6.0d", 0, " "},
332 {"%06.0d", 0, " "},
333 {"% d", 12345, " 12345"},
334 {"%+d", 12345, "+12345"},
335 {"%+d", -12345, "-12345"},
336 {"%b", 7, "111"},
337 {"%b", -6, "-110"},
338 {"%b", ^uint32(0), "11111111111111111111111111111111"},
339 {"%b", ^uint64(0), "1111111111111111111111111111111111111111111111111111111111111111"},
340 {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
341 {"%o", 01234, "1234"},
342 {"%#o", 01234, "01234"},
343 {"%o", ^uint32(0), "37777777777"},
344 {"%o", ^uint64(0), "1777777777777777777777"},
345 {"%#X", 0, "0X0"},
346 {"%x", 0x12abcdef, "12abcdef"},
347 {"%X", 0x12abcdef, "12ABCDEF"},
348 {"%x", ^uint32(0), "ffffffff"},
349 {"%X", ^uint64(0), "FFFFFFFFFFFFFFFF"},
350 {"%.20b", 7, "00000000000000000111"},
351 {"%10d", 12345, " 12345"},
352 {"%10d", -12345, " -12345"},
353 {"%+10d", 12345, " +12345"},
354 {"%010d", 12345, "0000012345"},
355 {"%010d", -12345, "-000012345"},
356 {"%20.8d", 1234, " 00001234"},
357 {"%20.8d", -1234, " -00001234"},
358 {"%020.8d", 1234, " 00001234"},
359 {"%020.8d", -1234, " -00001234"},
360 {"%-20.8d", 1234, "00001234 "},
361 {"%-20.8d", -1234, "-00001234 "},
362 {"%-#20.8x", 0x1234abc, "0x01234abc "},
363 {"%-#20.8X", 0x1234abc, "0X01234ABC "},
364 {"%-#20.8o", 01234, "00001234 "},
366 // Test correct f.intbuf overflow checks.
367 {"%068d", 1, zeroFill("", 68, "1")},
368 {"%068d", -1, zeroFill("-", 67, "1")},
369 {"%#.68x", 42, zeroFill("0x", 68, "2a")},
370 {"%.68d", -42, zeroFill("-", 68, "42")},
371 {"%+.68d", 42, zeroFill("+", 68, "42")},
372 {"% .68d", 42, zeroFill(" ", 68, "42")},
373 {"% +.68d", 42, zeroFill("+", 68, "42")},
375 // unicode format
376 {"%U", 0, "U+0000"},
377 {"%U", -1, "U+FFFFFFFFFFFFFFFF"},
378 {"%U", '\n', `U+000A`},
379 {"%#U", '\n', `U+000A`},
380 {"%+U", 'x', `U+0078`}, // Plus flag should have no effect.
381 {"%# U", 'x', `U+0078 'x'`}, // Space flag should have no effect.
382 {"%#.2U", 'x', `U+0078 'x'`}, // Precisions below 4 should print 4 digits.
383 {"%U", '\u263a', `U+263A`},
384 {"%#U", '\u263a', `U+263A '☺'`},
385 {"%U", '\U0001D6C2', `U+1D6C2`},
386 {"%#U", '\U0001D6C2', `U+1D6C2 '𝛂'`},
387 {"%#14.6U", '⌘', " U+002318 '⌘'"},
388 {"%#-14.6U", '⌘', "U+002318 '⌘' "},
389 {"%#014.6U", '⌘', " U+002318 '⌘'"},
390 {"%#-014.6U", '⌘', "U+002318 '⌘' "},
391 {"%.68U", uint(42), zeroFill("U+", 68, "2A")},
392 {"%#.68U", '日', zeroFill("U+", 68, "65E5") + " '日'"},
394 // floats
395 {"%+.3e", 0.0, "+0.000e+00"},
396 {"%+.3e", 1.0, "+1.000e+00"},
397 {"%+.3f", -1.0, "-1.000"},
398 {"%+.3F", -1.0, "-1.000"},
399 {"%+.3F", float32(-1.0), "-1.000"},
400 {"%+07.2f", 1.0, "+001.00"},
401 {"%+07.2f", -1.0, "-001.00"},
402 {"%-07.2f", 1.0, "1.00 "},
403 {"%-07.2f", -1.0, "-1.00 "},
404 {"%+-07.2f", 1.0, "+1.00 "},
405 {"%+-07.2f", -1.0, "-1.00 "},
406 {"%-+07.2f", 1.0, "+1.00 "},
407 {"%-+07.2f", -1.0, "-1.00 "},
408 {"%+10.2f", +1.0, " +1.00"},
409 {"%+10.2f", -1.0, " -1.00"},
410 {"% .3E", -1.0, "-1.000E+00"},
411 {"% .3e", 1.0, " 1.000e+00"},
412 {"%+.3g", 0.0, "+0"},
413 {"%+.3g", 1.0, "+1"},
414 {"%+.3g", -1.0, "-1"},
415 {"% .3g", -1.0, "-1"},
416 {"% .3g", 1.0, " 1"},
417 {"%b", float32(1.0), "8388608p-23"},
418 {"%b", 1.0, "4503599627370496p-52"},
419 // Precision has no effect for binary float format.
420 {"%.4b", float32(1.0), "8388608p-23"},
421 {"%.4b", -1.0, "-4503599627370496p-52"},
422 // Test correct f.intbuf boundary checks.
423 {"%.68f", 1.0, zeroFill("1.", 68, "")},
424 {"%.68f", -1.0, zeroFill("-1.", 68, "")},
425 // float infinites and NaNs
426 {"%f", posInf, "+Inf"},
427 {"%.1f", negInf, "-Inf"},
428 {"% f", NaN, " NaN"},
429 {"%20f", posInf, " +Inf"},
430 {"% 20F", posInf, " Inf"},
431 {"% 20e", negInf, " -Inf"},
432 {"%+20E", negInf, " -Inf"},
433 {"% +20g", negInf, " -Inf"},
434 {"%+-20G", posInf, "+Inf "},
435 {"%20e", NaN, " NaN"},
436 {"% +20E", NaN, " +NaN"},
437 {"% -20g", NaN, " NaN "},
438 {"%+-20G", NaN, "+NaN "},
439 // Zero padding does not apply to infinities and NaN.
440 {"%+020e", posInf, " +Inf"},
441 {"%-020f", negInf, "-Inf "},
442 {"%-020E", NaN, "NaN "},
444 // complex values
445 {"%.f", 0i, "(0+0i)"},
446 {"% .f", 0i, "( 0+0i)"},
447 {"%+.f", 0i, "(+0+0i)"},
448 {"% +.f", 0i, "(+0+0i)"},
449 {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
450 {"%+.3f", 0i, "(+0.000+0.000i)"},
451 {"%+.3g", 0i, "(+0+0i)"},
452 {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
453 {"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
454 {"%+.3g", 1 + 2i, "(+1+2i)"},
455 {"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
456 {"%.3f", 0i, "(0.000+0.000i)"},
457 {"%.3F", 0i, "(0.000+0.000i)"},
458 {"%.3F", complex64(0i), "(0.000+0.000i)"},
459 {"%.3g", 0i, "(0+0i)"},
460 {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
461 {"%.3f", 1 + 2i, "(1.000+2.000i)"},
462 {"%.3g", 1 + 2i, "(1+2i)"},
463 {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
464 {"%.3f", -1 - 2i, "(-1.000-2.000i)"},
465 {"%.3g", -1 - 2i, "(-1-2i)"},
466 {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
467 {"%+.3g", 1 + 2i, "(+1+2i)"},
468 {"%+.3g", complex64(1 + 2i), "(+1+2i)"},
469 {"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
470 {"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
471 // Precision has no effect for binary complex format.
472 {"%.4b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
473 {"%.4b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
474 // complex infinites and NaNs
475 {"%f", complex(posInf, posInf), "(+Inf+Infi)"},
476 {"%f", complex(negInf, negInf), "(-Inf-Infi)"},
477 {"%f", complex(NaN, NaN), "(NaN+NaNi)"},
478 {"%.1f", complex(posInf, posInf), "(+Inf+Infi)"},
479 {"% f", complex(posInf, posInf), "( Inf+Infi)"},
480 {"% f", complex(negInf, negInf), "(-Inf-Infi)"},
481 {"% f", complex(NaN, NaN), "( NaN+NaNi)"},
482 {"%8e", complex(posInf, posInf), "( +Inf +Infi)"},
483 {"% 8E", complex(posInf, posInf), "( Inf +Infi)"},
484 {"%+8f", complex(negInf, negInf), "( -Inf -Infi)"},
485 {"% +8g", complex(negInf, negInf), "( -Inf -Infi)"},
486 {"% -8G", complex(NaN, NaN), "( NaN +NaN i)"},
487 {"%+-8b", complex(NaN, NaN), "(+NaN +NaN i)"},
488 // Zero padding does not apply to infinities and NaN.
489 {"%08f", complex(posInf, posInf), "( +Inf +Infi)"},
490 {"%-08g", complex(negInf, negInf), "(-Inf -Inf i)"},
491 {"%-08G", complex(NaN, NaN), "(NaN +NaN i)"},
493 // old test/fmt_test.go
494 {"%e", 1.0, "1.000000e+00"},
495 {"%e", 1234.5678e3, "1.234568e+06"},
496 {"%e", 1234.5678e-8, "1.234568e-05"},
497 {"%e", -7.0, "-7.000000e+00"},
498 {"%e", -1e-9, "-1.000000e-09"},
499 {"%f", 1234.5678e3, "1234567.800000"},
500 {"%f", 1234.5678e-8, "0.000012"},
501 {"%f", -7.0, "-7.000000"},
502 {"%f", -1e-9, "-0.000000"},
503 {"%g", 1234.5678e3, "1.2345678e+06"},
504 {"%g", float32(1234.5678e3), "1.2345678e+06"},
505 {"%g", 1234.5678e-8, "1.2345678e-05"},
506 {"%g", -7.0, "-7"},
507 {"%g", -1e-9, "-1e-09"},
508 {"%g", float32(-1e-9), "-1e-09"},
509 {"%E", 1.0, "1.000000E+00"},
510 {"%E", 1234.5678e3, "1.234568E+06"},
511 {"%E", 1234.5678e-8, "1.234568E-05"},
512 {"%E", -7.0, "-7.000000E+00"},
513 {"%E", -1e-9, "-1.000000E-09"},
514 {"%G", 1234.5678e3, "1.2345678E+06"},
515 {"%G", float32(1234.5678e3), "1.2345678E+06"},
516 {"%G", 1234.5678e-8, "1.2345678E-05"},
517 {"%G", -7.0, "-7"},
518 {"%G", -1e-9, "-1E-09"},
519 {"%G", float32(-1e-9), "-1E-09"},
520 {"%20.5s", "qwertyuiop", " qwert"},
521 {"%.5s", "qwertyuiop", "qwert"},
522 {"%-20.5s", "qwertyuiop", "qwert "},
523 {"%20c", 'x', " x"},
524 {"%-20c", 'x', "x "},
525 {"%20.6e", 1.2345e3, " 1.234500e+03"},
526 {"%20.6e", 1.2345e-3, " 1.234500e-03"},
527 {"%20e", 1.2345e3, " 1.234500e+03"},
528 {"%20e", 1.2345e-3, " 1.234500e-03"},
529 {"%20.8e", 1.2345e3, " 1.23450000e+03"},
530 {"%20f", 1.23456789e3, " 1234.567890"},
531 {"%20f", 1.23456789e-3, " 0.001235"},
532 {"%20f", 12345678901.23456789, " 12345678901.234568"},
533 {"%-20f", 1.23456789e3, "1234.567890 "},
534 {"%20.8f", 1.23456789e3, " 1234.56789000"},
535 {"%20.8f", 1.23456789e-3, " 0.00123457"},
536 {"%g", 1.23456789e3, "1234.56789"},
537 {"%g", 1.23456789e-3, "0.00123456789"},
538 {"%g", 1.23456789e20, "1.23456789e+20"},
540 // arrays
541 {"%v", array, "[1 2 3 4 5]"},
542 {"%v", iarray, "[1 hello 2.5 <nil>]"},
543 {"%v", barray, "[1 2 3 4 5]"},
544 {"%v", &array, "&[1 2 3 4 5]"},
545 {"%v", &iarray, "&[1 hello 2.5 <nil>]"},
546 {"%v", &barray, "&[1 2 3 4 5]"},
548 // slices
549 {"%v", slice, "[1 2 3 4 5]"},
550 {"%v", islice, "[1 hello 2.5 <nil>]"},
551 {"%v", bslice, "[1 2 3 4 5]"},
552 {"%v", &slice, "&[1 2 3 4 5]"},
553 {"%v", &islice, "&[1 hello 2.5 <nil>]"},
554 {"%v", &bslice, "&[1 2 3 4 5]"},
556 // byte arrays and slices with %b,%c,%d,%o,%U and %v
557 {"%b", [3]byte{65, 66, 67}, "[1000001 1000010 1000011]"},
558 {"%c", [3]byte{65, 66, 67}, "[A B C]"},
559 {"%d", [3]byte{65, 66, 67}, "[65 66 67]"},
560 {"%o", [3]byte{65, 66, 67}, "[101 102 103]"},
561 {"%U", [3]byte{65, 66, 67}, "[U+0041 U+0042 U+0043]"},
562 {"%v", [3]byte{65, 66, 67}, "[65 66 67]"},
563 {"%v", [1]byte{123}, "[123]"},
564 {"%012v", []byte{}, "[]"},
565 {"%#012v", []byte{}, "[]byte{}"},
566 {"%6v", []byte{1, 11, 111}, "[ 1 11 111]"},
567 {"%06v", []byte{1, 11, 111}, "[000001 000011 000111]"},
568 {"%-6v", []byte{1, 11, 111}, "[1 11 111 ]"},
569 {"%-06v", []byte{1, 11, 111}, "[1 11 111 ]"},
570 {"%#v", []byte{1, 11, 111}, "[]byte{0x1, 0xb, 0x6f}"},
571 {"%#6v", []byte{1, 11, 111}, "[]byte{ 0x1, 0xb, 0x6f}"},
572 {"%#06v", []byte{1, 11, 111}, "[]byte{0x000001, 0x00000b, 0x00006f}"},
573 {"%#-6v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
574 {"%#-06v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
575 // f.space should and f.plus should not have an effect with %v.
576 {"% v", []byte{1, 11, 111}, "[ 1 11 111]"},
577 {"%+v", [3]byte{1, 11, 111}, "[1 11 111]"},
578 {"%# -6v", []byte{1, 11, 111}, "[]byte{ 0x1 , 0xb , 0x6f }"},
579 {"%#+-6v", [3]byte{1, 11, 111}, "[3]uint8{0x1 , 0xb , 0x6f }"},
580 // f.space and f.plus should have an effect with %d.
581 {"% d", []byte{1, 11, 111}, "[ 1 11 111]"},
582 {"%+d", [3]byte{1, 11, 111}, "[+1 +11 +111]"},
583 {"%# -6d", []byte{1, 11, 111}, "[ 1 11 111 ]"},
584 {"%#+-6d", [3]byte{1, 11, 111}, "[+1 +11 +111 ]"},
586 // floates with %v
587 {"%v", 1.2345678, "1.2345678"},
588 {"%v", float32(1.2345678), "1.2345678"},
590 // complexes with %v
591 {"%v", 1 + 2i, "(1+2i)"},
592 {"%v", complex64(1 + 2i), "(1+2i)"},
594 // structs
595 {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
596 {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
598 // +v on structs with Stringable items
599 {"%+v", B{1, 2}, `{I:<1> j:2}`},
600 {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
602 // other formats on Stringable items
603 {"%s", I(23), `<23>`},
604 {"%q", I(23), `"<23>"`},
605 {"%x", I(23), `3c32333e`},
606 {"%#x", I(23), `0x3c32333e`},
607 {"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
608 // Stringer applies only to string formats.
609 {"%d", I(23), `23`},
610 // Stringer applies to the extracted value.
611 {"%s", reflect.ValueOf(I(23)), `<23>`},
613 // go syntax
614 {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
615 {"%#v", new(byte), "(*uint8)(0xPTR)"},
616 {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
617 {"%#v", make(chan int), "(chan int)(0xPTR)"},
618 {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
619 {"%#v", 1000000000, "1000000000"},
620 {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
621 {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
622 {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
623 {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
624 {"%#v", []int(nil), `[]int(nil)`},
625 {"%#v", []int{}, `[]int{}`},
626 {"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
627 {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
628 {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
629 {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
630 {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
631 {"%#v", map[int]byte{}, `map[int]uint8{}`},
632 {"%#v", "foo", `"foo"`},
633 {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
634 {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
635 {"%#v", []int32(nil), "[]int32(nil)"},
636 {"%#v", 1.2345678, "1.2345678"},
637 {"%#v", float32(1.2345678), "1.2345678"},
638 // Only print []byte and []uint8 as type []byte if they appear at the top level.
639 {"%#v", []byte(nil), "[]byte(nil)"},
640 {"%#v", []uint8(nil), "[]byte(nil)"},
641 {"%#v", []byte{}, "[]byte{}"},
642 {"%#v", []uint8{}, "[]byte{}"},
643 {"%#v", reflect.ValueOf([]byte{}), "[]uint8{}"},
644 {"%#v", reflect.ValueOf([]uint8{}), "[]uint8{}"},
645 {"%#v", &[]byte{}, "&[]uint8{}"},
646 {"%#v", &[]byte{}, "&[]uint8{}"},
647 {"%#v", [3]byte{}, "[3]uint8{0x0, 0x0, 0x0}"},
648 {"%#v", [3]uint8{}, "[3]uint8{0x0, 0x0, 0x0}"},
650 // slices with other formats
651 {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
652 {"%x", []int{1, 2, 15}, `[1 2 f]`},
653 {"%d", []int{1, 2, 15}, `[1 2 15]`},
654 {"%d", []byte{1, 2, 15}, `[1 2 15]`},
655 {"%q", []string{"a", "b"}, `["a" "b"]`},
656 {"% 02x", []byte{1}, "01"},
657 {"% 02x", []byte{1, 2, 3}, "01 02 03"},
659 // Padding with byte slices.
660 {"%2x", []byte{}, " "},
661 {"%#2x", []byte{}, " "},
662 {"% 02x", []byte{}, "00"},
663 {"%# 02x", []byte{}, "00"},
664 {"%-2x", []byte{}, " "},
665 {"%-02x", []byte{}, " "},
666 {"%8x", []byte{0xab}, " ab"},
667 {"% 8x", []byte{0xab}, " ab"},
668 {"%#8x", []byte{0xab}, " 0xab"},
669 {"%# 8x", []byte{0xab}, " 0xab"},
670 {"%08x", []byte{0xab}, "000000ab"},
671 {"% 08x", []byte{0xab}, "000000ab"},
672 {"%#08x", []byte{0xab}, "00000xab"},
673 {"%# 08x", []byte{0xab}, "00000xab"},
674 {"%10x", []byte{0xab, 0xcd}, " abcd"},
675 {"% 10x", []byte{0xab, 0xcd}, " ab cd"},
676 {"%#10x", []byte{0xab, 0xcd}, " 0xabcd"},
677 {"%# 10x", []byte{0xab, 0xcd}, " 0xab 0xcd"},
678 {"%010x", []byte{0xab, 0xcd}, "000000abcd"},
679 {"% 010x", []byte{0xab, 0xcd}, "00000ab cd"},
680 {"%#010x", []byte{0xab, 0xcd}, "00000xabcd"},
681 {"%# 010x", []byte{0xab, 0xcd}, "00xab 0xcd"},
682 {"%-10X", []byte{0xab}, "AB "},
683 {"% -010X", []byte{0xab}, "AB "},
684 {"%#-10X", []byte{0xab, 0xcd}, "0XABCD "},
685 {"%# -010X", []byte{0xab, 0xcd}, "0XAB 0XCD "},
686 // Same for strings
687 {"%2x", "", " "},
688 {"%#2x", "", " "},
689 {"% 02x", "", "00"},
690 {"%# 02x", "", "00"},
691 {"%-2x", "", " "},
692 {"%-02x", "", " "},
693 {"%8x", "\xab", " ab"},
694 {"% 8x", "\xab", " ab"},
695 {"%#8x", "\xab", " 0xab"},
696 {"%# 8x", "\xab", " 0xab"},
697 {"%08x", "\xab", "000000ab"},
698 {"% 08x", "\xab", "000000ab"},
699 {"%#08x", "\xab", "00000xab"},
700 {"%# 08x", "\xab", "00000xab"},
701 {"%10x", "\xab\xcd", " abcd"},
702 {"% 10x", "\xab\xcd", " ab cd"},
703 {"%#10x", "\xab\xcd", " 0xabcd"},
704 {"%# 10x", "\xab\xcd", " 0xab 0xcd"},
705 {"%010x", "\xab\xcd", "000000abcd"},
706 {"% 010x", "\xab\xcd", "00000ab cd"},
707 {"%#010x", "\xab\xcd", "00000xabcd"},
708 {"%# 010x", "\xab\xcd", "00xab 0xcd"},
709 {"%-10X", "\xab", "AB "},
710 {"% -010X", "\xab", "AB "},
711 {"%#-10X", "\xab\xcd", "0XABCD "},
712 {"%# -010X", "\xab\xcd", "0XAB 0XCD "},
714 // renamings
715 {"%v", renamedBool(true), "true"},
716 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
717 {"%o", renamedInt(8), "10"},
718 {"%d", renamedInt8(-9), "-9"},
719 {"%v", renamedInt16(10), "10"},
720 {"%v", renamedInt32(-11), "-11"},
721 {"%X", renamedInt64(255), "FF"},
722 {"%v", renamedUint(13), "13"},
723 {"%o", renamedUint8(14), "16"},
724 {"%X", renamedUint16(15), "F"},
725 {"%d", renamedUint32(16), "16"},
726 {"%X", renamedUint64(17), "11"},
727 {"%o", renamedUintptr(18), "22"},
728 {"%x", renamedString("thing"), "7468696e67"},
729 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
730 {"%q", renamedBytes([]byte("hello")), `"hello"`},
731 {"%x", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656c6c6f"},
732 {"%X", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656C6C6F"},
733 {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
734 {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
735 {"%v", renamedFloat32(22), "22"},
736 {"%v", renamedFloat64(33), "33"},
737 {"%v", renamedComplex64(3 + 4i), "(3+4i)"},
738 {"%v", renamedComplex128(4 - 3i), "(4-3i)"},
740 // Formatter
741 {"%x", F(1), "<x=F(1)>"},
742 {"%x", G(2), "2"},
743 {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
745 // GoStringer
746 {"%#v", G(6), "GoString(6)"},
747 {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
749 // %T
750 {"%T", byte(0), "uint8"},
751 {"%T", reflect.ValueOf(nil), "reflect.Value"},
752 {"%T", (4 - 3i), "complex128"},
753 {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
754 {"%T", intVar, "int"},
755 {"%6T", &intVar, " *int"},
756 {"%10T", nil, " <nil>"},
757 {"%-10T", nil, "<nil> "},
759 // %p with pointers
760 {"%p", (*int)(nil), "0x0"},
761 {"%#p", (*int)(nil), "0"},
762 {"%p", &intVar, "0xPTR"},
763 {"%#p", &intVar, "PTR"},
764 {"%p", &array, "0xPTR"},
765 {"%p", &slice, "0xPTR"},
766 {"%8.2p", (*int)(nil), " 0x00"},
767 {"%-20.16p", &intVar, "0xPTR "},
768 // %p on non-pointers
769 {"%p", make(chan int), "0xPTR"},
770 {"%p", make(map[int]int), "0xPTR"},
771 {"%p", func() {}, "0xPTR"},
772 {"%p", 27, "%!p(int=27)"}, // not a pointer at all
773 {"%p", nil, "%!p(<nil>)"}, // nil on its own has no type ...
774 {"%#p", nil, "%!p(<nil>)"}, // ... and hence is not a pointer type.
775 // pointers with specified base
776 {"%b", &intVar, "PTR_b"},
777 {"%d", &intVar, "PTR_d"},
778 {"%o", &intVar, "PTR_o"},
779 {"%x", &intVar, "PTR_x"},
780 {"%X", &intVar, "PTR_X"},
781 // %v on pointers
782 {"%v", nil, "<nil>"},
783 {"%#v", nil, "<nil>"},
784 {"%v", (*int)(nil), "<nil>"},
785 {"%#v", (*int)(nil), "(*int)(nil)"},
786 {"%v", &intVar, "0xPTR"},
787 {"%#v", &intVar, "(*int)(0xPTR)"},
788 {"%8.2v", (*int)(nil), " <nil>"},
789 {"%-20.16v", &intVar, "0xPTR "},
790 // string method on pointer
791 {"%s", &pValue, "String(p)"}, // String method...
792 {"%p", &pValue, "0xPTR"}, // ... is not called with %p.
794 // %d on Stringer should give integer if possible
795 {"%s", time.Time{}.Month(), "January"},
796 {"%d", time.Time{}.Month(), "1"},
798 // erroneous things
799 {"", nil, "%!(EXTRA <nil>)"},
800 {"", 2, "%!(EXTRA int=2)"},
801 {"no args", "hello", "no args%!(EXTRA string=hello)"},
802 {"%s %", "hello", "hello %!(NOVERB)"},
803 {"%s %.2", "hello", "hello %!(NOVERB)"},
804 {"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)%!(EXTRA int=0)"},
805 {"%184467440737095516170v", 0, "%!(NOVERB)%!(EXTRA int=0)"},
806 // Extra argument errors should format without flags set.
807 {"%010.2", "12345", "%!(NOVERB)%!(EXTRA string=12345)"},
809 // The "<nil>" show up because maps are printed by
810 // first obtaining a list of keys and then looking up
811 // each key. Since NaNs can be map keys but cannot
812 // be fetched directly, the lookup fails and returns a
813 // zero reflect.Value, which formats as <nil>.
814 // This test is just to check that it shows the two NaNs at all.
815 {"%v", map[float64]int{NaN: 1, NaN: 2}, "map[NaN:<nil> NaN:<nil>]"},
817 // Comparison of padding rules with C printf.
819 C program:
820 #include <stdio.h>
822 char *format[] = {
823 "[%.2f]",
824 "[% .2f]",
825 "[%+.2f]",
826 "[%7.2f]",
827 "[% 7.2f]",
828 "[%+7.2f]",
829 "[% +7.2f]",
830 "[%07.2f]",
831 "[% 07.2f]",
832 "[%+07.2f]",
833 "[% +07.2f]"
836 int main(void) {
837 int i;
838 for(i = 0; i < 11; i++) {
839 printf("%s: ", format[i]);
840 printf(format[i], 1.0);
841 printf(" ");
842 printf(format[i], -1.0);
843 printf("\n");
847 Output:
848 [%.2f]: [1.00] [-1.00]
849 [% .2f]: [ 1.00] [-1.00]
850 [%+.2f]: [+1.00] [-1.00]
851 [%7.2f]: [ 1.00] [ -1.00]
852 [% 7.2f]: [ 1.00] [ -1.00]
853 [%+7.2f]: [ +1.00] [ -1.00]
854 [% +7.2f]: [ +1.00] [ -1.00]
855 [%07.2f]: [0001.00] [-001.00]
856 [% 07.2f]: [ 001.00] [-001.00]
857 [%+07.2f]: [+001.00] [-001.00]
858 [% +07.2f]: [+001.00] [-001.00]
861 {"%.2f", 1.0, "1.00"},
862 {"%.2f", -1.0, "-1.00"},
863 {"% .2f", 1.0, " 1.00"},
864 {"% .2f", -1.0, "-1.00"},
865 {"%+.2f", 1.0, "+1.00"},
866 {"%+.2f", -1.0, "-1.00"},
867 {"%7.2f", 1.0, " 1.00"},
868 {"%7.2f", -1.0, " -1.00"},
869 {"% 7.2f", 1.0, " 1.00"},
870 {"% 7.2f", -1.0, " -1.00"},
871 {"%+7.2f", 1.0, " +1.00"},
872 {"%+7.2f", -1.0, " -1.00"},
873 {"% +7.2f", 1.0, " +1.00"},
874 {"% +7.2f", -1.0, " -1.00"},
875 {"%07.2f", 1.0, "0001.00"},
876 {"%07.2f", -1.0, "-001.00"},
877 {"% 07.2f", 1.0, " 001.00"},
878 {"% 07.2f", -1.0, "-001.00"},
879 {"%+07.2f", 1.0, "+001.00"},
880 {"%+07.2f", -1.0, "-001.00"},
881 {"% +07.2f", 1.0, "+001.00"},
882 {"% +07.2f", -1.0, "-001.00"},
884 // Complex numbers: exhaustively tested in TestComplexFormatting.
885 {"%7.2f", 1 + 2i, "( 1.00 +2.00i)"},
886 {"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
888 // Use spaces instead of zero if padding to the right.
889 {"%0-5s", "abc", "abc "},
890 {"%-05.1f", 1.0, "1.0 "},
892 // float and complex formatting should not change the padding width
893 // for other elements. See issue 14642.
894 {"%06v", []interface{}{+10.0, 10}, "[000010 000010]"},
895 {"%06v", []interface{}{-10.0, 10}, "[-00010 000010]"},
896 {"%06v", []interface{}{+10.0 + 10i, 10}, "[(000010+00010i) 000010]"},
897 {"%06v", []interface{}{-10.0 + 10i, 10}, "[(-00010+00010i) 000010]"},
899 // integer formatting should not alter padding for other elements.
900 {"%03.6v", []interface{}{1, 2.0, "x"}, "[000001 002 00x]"},
901 {"%03.0v", []interface{}{0, 2.0, "x"}, "[ 002 000]"},
903 // Complex fmt used to leave the plus flag set for future entries in the array
904 // causing +2+0i and +3+0i instead of 2+0i and 3+0i.
905 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
906 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
908 // Incomplete format specification caused crash.
909 {"%.", 3, "%!.(int=3)"},
911 // Padding for complex numbers. Has been bad, then fixed, then bad again.
912 {"%+10.2f", +104.66 + 440.51i, "( +104.66 +440.51i)"},
913 {"%+10.2f", -104.66 + 440.51i, "( -104.66 +440.51i)"},
914 {"%+10.2f", +104.66 - 440.51i, "( +104.66 -440.51i)"},
915 {"%+10.2f", -104.66 - 440.51i, "( -104.66 -440.51i)"},
916 {"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"},
917 {"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"},
918 {"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"},
919 {"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
921 // []T where type T is a byte with a Stringer method.
922 {"%v", byteStringerSlice, "[X X X X X]"},
923 {"%s", byteStringerSlice, "hello"},
924 {"%q", byteStringerSlice, "\"hello\""},
925 {"%x", byteStringerSlice, "68656c6c6f"},
926 {"%X", byteStringerSlice, "68656C6C6F"},
927 {"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x68, 0x65, 0x6c, 0x6c, 0x6f}"},
929 // And the same for Formatter.
930 {"%v", byteFormatterSlice, "[X X X X X]"},
931 {"%s", byteFormatterSlice, "hello"},
932 {"%q", byteFormatterSlice, "\"hello\""},
933 {"%x", byteFormatterSlice, "68656c6c6f"},
934 {"%X", byteFormatterSlice, "68656C6C6F"},
935 // This next case seems wrong, but the docs say the Formatter wins here.
936 {"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X, X}"},
938 // reflect.Value handled specially in Go 1.5, making it possible to
939 // see inside non-exported fields (which cannot be accessed with Interface()).
940 // Issue 8965.
941 {"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"}, // Equivalent to the old way.
942 {"%v", reflect.ValueOf(A{}).Field(0), "0"}, // Sees inside the field.
944 // verbs apply to the extracted value too.
945 {"%s", reflect.ValueOf("hello"), "hello"},
946 {"%q", reflect.ValueOf("hello"), `"hello"`},
947 {"%#04x", reflect.ValueOf(256), "0x0100"},
949 // invalid reflect.Value doesn't crash.
950 {"%v", reflect.Value{}, "<invalid reflect.Value>"},
951 {"%v", &reflect.Value{}, "<invalid Value>"},
952 {"%v", SI{reflect.Value{}}, "{<invalid Value>}"},
954 // Tests to check that not supported verbs generate an error string.
955 {"%☠", nil, "%!☠(<nil>)"},
956 {"%☠", interface{}(nil), "%!☠(<nil>)"},
957 {"%☠", int(0), "%!☠(int=0)"},
958 {"%☠", uint(0), "%!☠(uint=0)"},
959 {"%☠", []byte{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
960 {"%☠", []uint8{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
961 {"%☠", [1]byte{0}, "[%!☠(uint8=0)]"},
962 {"%☠", [1]uint8{0}, "[%!☠(uint8=0)]"},
963 {"%☠", "hello", "%!☠(string=hello)"},
964 {"%☠", 1.2345678, "%!☠(float64=1.2345678)"},
965 {"%☠", float32(1.2345678), "%!☠(float32=1.2345678)"},
966 {"%☠", 1.2345678 + 1.2345678i, "%!☠(complex128=(1.2345678+1.2345678i))"},
967 {"%☠", complex64(1.2345678 + 1.2345678i), "%!☠(complex64=(1.2345678+1.2345678i))"},
968 {"%☠", &intVar, "%!☠(*int=0xPTR)"},
969 {"%☠", make(chan int), "%!☠(chan int=0xPTR)"},
970 {"%☠", func() {}, "%!☠(func()=0xPTR)"},
971 {"%☠", reflect.ValueOf(renamedInt(0)), "%!☠(fmt_test.renamedInt=0)"},
972 {"%☠", SI{renamedInt(0)}, "{%!☠(fmt_test.renamedInt=0)}"},
973 {"%☠", &[]interface{}{I(1), G(2)}, "&[%!☠(fmt_test.I=1) %!☠(fmt_test.G=2)]"},
974 {"%☠", SI{&[]interface{}{I(1), G(2)}}, "{%!☠(*[]interface {}=&[1 2])}"},
975 {"%☠", reflect.Value{}, "<invalid reflect.Value>"},
976 {"%☠", map[float64]int{NaN: 1}, "map[%!☠(float64=NaN):%!☠(<nil>)]"},
979 // zeroFill generates zero-filled strings of the specified width. The length
980 // of the suffix (but not the prefix) is compensated for in the width calculation.
981 func zeroFill(prefix string, width int, suffix string) string {
982 return prefix + strings.Repeat("0", width-len(suffix)) + suffix
985 func TestSprintf(t *testing.T) {
986 for _, tt := range fmtTests {
987 s := Sprintf(tt.fmt, tt.val)
988 i := strings.Index(tt.out, "PTR")
989 if i >= 0 && i < len(s) {
990 var pattern, chars string
991 switch {
992 case strings.HasPrefix(tt.out[i:], "PTR_b"):
993 pattern = "PTR_b"
994 chars = "01"
995 case strings.HasPrefix(tt.out[i:], "PTR_o"):
996 pattern = "PTR_o"
997 chars = "01234567"
998 case strings.HasPrefix(tt.out[i:], "PTR_d"):
999 pattern = "PTR_d"
1000 chars = "0123456789"
1001 case strings.HasPrefix(tt.out[i:], "PTR_x"):
1002 pattern = "PTR_x"
1003 chars = "0123456789abcdef"
1004 case strings.HasPrefix(tt.out[i:], "PTR_X"):
1005 pattern = "PTR_X"
1006 chars = "0123456789ABCDEF"
1007 default:
1008 pattern = "PTR"
1009 chars = "0123456789abcdefABCDEF"
1011 p := s[:i] + pattern
1012 for j := i; j < len(s); j++ {
1013 if !strings.ContainsRune(chars, rune(s[j])) {
1014 p += s[j:]
1015 break
1018 s = p
1020 if s != tt.out {
1021 if _, ok := tt.val.(string); ok {
1022 // Don't requote the already-quoted strings.
1023 // It's too confusing to read the errors.
1024 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
1025 } else {
1026 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
1032 // TestComplexFormatting checks that a complex always formats to the same
1033 // thing as if done by hand with two singleton prints.
1034 func TestComplexFormatting(t *testing.T) {
1035 var yesNo = []bool{true, false}
1036 var values = []float64{1, 0, -1, posInf, negInf, NaN}
1037 for _, plus := range yesNo {
1038 for _, zero := range yesNo {
1039 for _, space := range yesNo {
1040 for _, char := range "fFeEgG" {
1041 realFmt := "%"
1042 if zero {
1043 realFmt += "0"
1045 if space {
1046 realFmt += " "
1048 if plus {
1049 realFmt += "+"
1051 realFmt += "10.2"
1052 realFmt += string(char)
1053 // Imaginary part always has a sign, so force + and ignore space.
1054 imagFmt := "%"
1055 if zero {
1056 imagFmt += "0"
1058 imagFmt += "+"
1059 imagFmt += "10.2"
1060 imagFmt += string(char)
1061 for _, realValue := range values {
1062 for _, imagValue := range values {
1063 one := Sprintf(realFmt, complex(realValue, imagValue))
1064 two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
1065 if one != two {
1066 t.Error(f, one, two)
1076 type SE []interface{} // slice of empty; notational compactness.
1078 var reorderTests = []struct {
1079 fmt string
1080 val SE
1081 out string
1083 {"%[1]d", SE{1}, "1"},
1084 {"%[2]d", SE{2, 1}, "1"},
1085 {"%[2]d %[1]d", SE{1, 2}, "2 1"},
1086 {"%[2]*[1]d", SE{2, 5}, " 2"},
1087 {"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line.
1088 {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
1089 {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
1090 {"%10f", SE{12.0}, " 12.000000"},
1091 {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
1092 {"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line.
1093 {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
1094 {"%6.f", SE{12.0}, " 12"}, // // Explicit version of next line; empty precision means zero.
1095 {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"},
1096 // An actual use! Print the same arguments twice.
1097 {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
1099 // Erroneous cases.
1100 {"%[d", SE{2, 1}, "%!d(BADINDEX)"},
1101 {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
1102 {"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
1103 {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
1104 {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
1105 {"%[3]", SE{2, 1}, "%!(NOVERB)"},
1106 {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
1107 {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
1108 {"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
1109 {"%.[2]d", SE{7}, "%!d(BADINDEX)"},
1110 {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
1111 {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
1112 {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
1113 {"%.[]", SE{}, "%!](BADINDEX)"}, // Issue 10675
1114 {"%.-3d", SE{42}, "%!-(int=42)3d"}, // TODO: Should this set return better error messages?
1115 {"%2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1116 {"%-2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1117 {"%.2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1120 func TestReorder(t *testing.T) {
1121 for _, tt := range reorderTests {
1122 s := Sprintf(tt.fmt, tt.val...)
1123 if s != tt.out {
1124 t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
1125 } else {
1130 func BenchmarkSprintfPadding(b *testing.B) {
1131 b.RunParallel(func(pb *testing.PB) {
1132 for pb.Next() {
1133 Sprintf("%16f", 1.0)
1138 func BenchmarkSprintfEmpty(b *testing.B) {
1139 b.RunParallel(func(pb *testing.PB) {
1140 for pb.Next() {
1141 Sprintf("")
1146 func BenchmarkSprintfString(b *testing.B) {
1147 b.RunParallel(func(pb *testing.PB) {
1148 for pb.Next() {
1149 Sprintf("%s", "hello")
1154 func BenchmarkSprintfTruncateString(b *testing.B) {
1155 b.RunParallel(func(pb *testing.PB) {
1156 for pb.Next() {
1157 Sprintf("%.3s", "日本語日本語日本語")
1162 func BenchmarkSprintfQuoteString(b *testing.B) {
1163 b.RunParallel(func(pb *testing.PB) {
1164 for pb.Next() {
1165 Sprintf("%q", "日本語日本語日本語")
1170 func BenchmarkSprintfInt(b *testing.B) {
1171 b.RunParallel(func(pb *testing.PB) {
1172 for pb.Next() {
1173 Sprintf("%d", 5)
1178 func BenchmarkSprintfIntInt(b *testing.B) {
1179 b.RunParallel(func(pb *testing.PB) {
1180 for pb.Next() {
1181 Sprintf("%d %d", 5, 6)
1186 func BenchmarkSprintfPrefixedInt(b *testing.B) {
1187 b.RunParallel(func(pb *testing.PB) {
1188 for pb.Next() {
1189 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
1194 func BenchmarkSprintfFloat(b *testing.B) {
1195 b.RunParallel(func(pb *testing.PB) {
1196 for pb.Next() {
1197 Sprintf("%g", 5.23184)
1202 func BenchmarkSprintfComplex(b *testing.B) {
1203 b.RunParallel(func(pb *testing.PB) {
1204 for pb.Next() {
1205 Sprintf("%f", 5.23184+5.23184i)
1210 func BenchmarkSprintfBoolean(b *testing.B) {
1211 b.RunParallel(func(pb *testing.PB) {
1212 for pb.Next() {
1213 Sprintf("%t", true)
1218 func BenchmarkSprintfHexString(b *testing.B) {
1219 b.RunParallel(func(pb *testing.PB) {
1220 for pb.Next() {
1221 Sprintf("% #x", "0123456789abcdef")
1226 func BenchmarkSprintfHexBytes(b *testing.B) {
1227 data := []byte("0123456789abcdef")
1228 b.RunParallel(func(pb *testing.PB) {
1229 for pb.Next() {
1230 Sprintf("% #x", data)
1235 func BenchmarkSprintfBytes(b *testing.B) {
1236 data := []byte("0123456789abcdef")
1237 b.RunParallel(func(pb *testing.PB) {
1238 for pb.Next() {
1239 Sprintf("%v", data)
1244 func BenchmarkSprintfStringer(b *testing.B) {
1245 stringer := I(12345)
1246 b.RunParallel(func(pb *testing.PB) {
1247 for pb.Next() {
1248 Sprintf("%v", stringer)
1253 func BenchmarkSprintfStructure(b *testing.B) {
1254 s := &[]interface{}{SI{12345}, map[int]string{0: "hello"}}
1255 b.RunParallel(func(pb *testing.PB) {
1256 for pb.Next() {
1257 Sprintf("%#v", s)
1262 func BenchmarkManyArgs(b *testing.B) {
1263 b.RunParallel(func(pb *testing.PB) {
1264 var buf bytes.Buffer
1265 for pb.Next() {
1266 buf.Reset()
1267 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
1272 func BenchmarkFprintInt(b *testing.B) {
1273 var buf bytes.Buffer
1274 for i := 0; i < b.N; i++ {
1275 buf.Reset()
1276 Fprint(&buf, 123456)
1280 func BenchmarkFprintfBytes(b *testing.B) {
1281 data := []byte(string("0123456789"))
1282 var buf bytes.Buffer
1283 for i := 0; i < b.N; i++ {
1284 buf.Reset()
1285 Fprintf(&buf, "%s", data)
1289 func BenchmarkFprintIntNoAlloc(b *testing.B) {
1290 var x interface{} = 123456
1291 var buf bytes.Buffer
1292 for i := 0; i < b.N; i++ {
1293 buf.Reset()
1294 Fprint(&buf, x)
1298 var mallocBuf bytes.Buffer
1299 var mallocPointer *int // A pointer so we know the interface value won't allocate.
1301 // gccgo numbers are different because gccgo does not have escape
1302 // analysis yet.
1303 var mallocTest = []struct {
1304 count int
1305 desc string
1306 fn func()
1308 {5, `Sprintf("")`, func() { Sprintf("") }},
1309 {5, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
1310 {5, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
1311 {5, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
1312 {5, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
1313 {20, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1?
1314 {5, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
1315 // If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
1316 {5, `Fprintf(buf, "%x %x %x")`, func() {
1317 mallocBuf.Reset()
1318 Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer)
1322 var _ bytes.Buffer
1324 func TestCountMallocs(t *testing.T) {
1325 switch {
1326 case testing.Short():
1327 t.Skip("skipping malloc count in short mode")
1328 case runtime.GOMAXPROCS(0) > 1:
1329 t.Skip("skipping; GOMAXPROCS>1")
1330 case race.Enabled:
1331 t.Skip("skipping malloc count under race detector")
1333 for _, mt := range mallocTest {
1334 mallocs := testing.AllocsPerRun(100, mt.fn)
1335 if got, max := mallocs, float64(mt.count); got > max {
1336 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
1341 type flagPrinter struct{}
1343 func (flagPrinter) Format(f State, c rune) {
1344 s := "%"
1345 for i := 0; i < 128; i++ {
1346 if f.Flag(i) {
1347 s += string(i)
1350 if w, ok := f.Width(); ok {
1351 s += Sprintf("%d", w)
1353 if p, ok := f.Precision(); ok {
1354 s += Sprintf(".%d", p)
1356 s += string(c)
1357 io.WriteString(f, "["+s+"]")
1360 var flagtests = []struct {
1361 in string
1362 out string
1364 {"%a", "[%a]"},
1365 {"%-a", "[%-a]"},
1366 {"%+a", "[%+a]"},
1367 {"%#a", "[%#a]"},
1368 {"% a", "[% a]"},
1369 {"%0a", "[%0a]"},
1370 {"%1.2a", "[%1.2a]"},
1371 {"%-1.2a", "[%-1.2a]"},
1372 {"%+1.2a", "[%+1.2a]"},
1373 {"%-+1.2a", "[%+-1.2a]"},
1374 {"%-+1.2abc", "[%+-1.2a]bc"},
1375 {"%-1.2abc", "[%-1.2a]bc"},
1378 func TestFlagParser(t *testing.T) {
1379 var flagprinter flagPrinter
1380 for _, tt := range flagtests {
1381 s := Sprintf(tt.in, &flagprinter)
1382 if s != tt.out {
1383 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
1388 func TestStructPrinter(t *testing.T) {
1389 type T struct {
1390 a string
1391 b string
1392 c int
1394 var s T
1395 s.a = "abc"
1396 s.b = "def"
1397 s.c = 123
1398 var tests = []struct {
1399 fmt string
1400 out string
1402 {"%v", "{abc def 123}"},
1403 {"%+v", "{a:abc b:def c:123}"},
1404 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`},
1406 for _, tt := range tests {
1407 out := Sprintf(tt.fmt, s)
1408 if out != tt.out {
1409 t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
1411 // The same but with a pointer.
1412 out = Sprintf(tt.fmt, &s)
1413 if out != "&"+tt.out {
1414 t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
1419 func TestSlicePrinter(t *testing.T) {
1420 slice := []int{}
1421 s := Sprint(slice)
1422 if s != "[]" {
1423 t.Errorf("empty slice printed as %q not %q", s, "[]")
1425 slice = []int{1, 2, 3}
1426 s = Sprint(slice)
1427 if s != "[1 2 3]" {
1428 t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
1430 s = Sprint(&slice)
1431 if s != "&[1 2 3]" {
1432 t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
1436 // presentInMap checks map printing using substrings so we don't depend on the
1437 // print order.
1438 func presentInMap(s string, a []string, t *testing.T) {
1439 for i := 0; i < len(a); i++ {
1440 loc := strings.Index(s, a[i])
1441 if loc < 0 {
1442 t.Errorf("map print: expected to find %q in %q", a[i], s)
1444 // make sure the match ends here
1445 loc += len(a[i])
1446 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
1447 t.Errorf("map print: %q not properly terminated in %q", a[i], s)
1452 func TestMapPrinter(t *testing.T) {
1453 m0 := make(map[int]string)
1454 s := Sprint(m0)
1455 if s != "map[]" {
1456 t.Errorf("empty map printed as %q not %q", s, "map[]")
1458 m1 := map[int]string{1: "one", 2: "two", 3: "three"}
1459 a := []string{"1:one", "2:two", "3:three"}
1460 presentInMap(Sprintf("%v", m1), a, t)
1461 presentInMap(Sprint(m1), a, t)
1462 // Pointer to map prints the same but with initial &.
1463 if !strings.HasPrefix(Sprint(&m1), "&") {
1464 t.Errorf("no initial & for address of map")
1466 presentInMap(Sprintf("%v", &m1), a, t)
1467 presentInMap(Sprint(&m1), a, t)
1470 func TestEmptyMap(t *testing.T) {
1471 const emptyMapStr = "map[]"
1472 var m map[string]int
1473 s := Sprint(m)
1474 if s != emptyMapStr {
1475 t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
1477 m = make(map[string]int)
1478 s = Sprint(m)
1479 if s != emptyMapStr {
1480 t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
1484 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
1485 // right places, that is, between arg pairs in which neither is a string.
1486 func TestBlank(t *testing.T) {
1487 got := Sprint("<", 1, ">:", 1, 2, 3, "!")
1488 expect := "<1>:1 2 3!"
1489 if got != expect {
1490 t.Errorf("got %q expected %q", got, expect)
1494 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
1495 // the right places, that is, between all arg pairs.
1496 func TestBlankln(t *testing.T) {
1497 got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
1498 expect := "< 1 >: 1 2 3 !\n"
1499 if got != expect {
1500 t.Errorf("got %q expected %q", got, expect)
1504 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
1505 func TestFormatterPrintln(t *testing.T) {
1506 f := F(1)
1507 expect := "<v=F(1)>\n"
1508 s := Sprint(f, "\n")
1509 if s != expect {
1510 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
1512 s = Sprintln(f)
1513 if s != expect {
1514 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
1516 s = Sprintf("%v\n", f)
1517 if s != expect {
1518 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
1522 func args(a ...interface{}) []interface{} { return a }
1524 var startests = []struct {
1525 fmt string
1526 in []interface{}
1527 out string
1529 {"%*d", args(4, 42), " 42"},
1530 {"%-*d", args(4, 42), "42 "},
1531 {"%*d", args(-4, 42), "42 "},
1532 {"%-*d", args(-4, 42), "42 "},
1533 {"%.*d", args(4, 42), "0042"},
1534 {"%*.*d", args(8, 4, 42), " 0042"},
1535 {"%0*d", args(4, 42), "0042"},
1536 // Some non-int types for width. (Issue 10732).
1537 {"%0*d", args(uint(4), 42), "0042"},
1538 {"%0*d", args(uint64(4), 42), "0042"},
1539 {"%0*d", args('\x04', 42), "0042"},
1540 {"%0*d", args(uintptr(4), 42), "0042"},
1542 // erroneous
1543 {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
1544 {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"},
1545 {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"},
1546 {"%.*d", args(nil, 42), "%!(BADPREC)42"},
1547 {"%.*d", args(-1, 42), "%!(BADPREC)42"},
1548 {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"},
1549 {"%.*d", args(uint(1e7), 42), "%!(BADPREC)42"},
1550 {"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"}, // Huge negative (-inf).
1551 {"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"}, // Small negative (-1).
1552 {"%*d", args(5, "foo"), "%!d(string= foo)"},
1553 {"%*% %d", args(20, 5), "% 5"},
1554 {"%*", args(4), "%!(NOVERB)"},
1557 func TestWidthAndPrecision(t *testing.T) {
1558 for i, tt := range startests {
1559 s := Sprintf(tt.fmt, tt.in...)
1560 if s != tt.out {
1561 t.Errorf("#%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
1566 // PanicS is a type that panics in String.
1567 type PanicS struct {
1568 message interface{}
1571 // Value receiver.
1572 func (p PanicS) String() string {
1573 panic(p.message)
1576 // PanicGo is a type that panics in GoString.
1577 type PanicGo struct {
1578 message interface{}
1581 // Value receiver.
1582 func (p PanicGo) GoString() string {
1583 panic(p.message)
1586 // PanicF is a type that panics in Format.
1587 type PanicF struct {
1588 message interface{}
1591 // Value receiver.
1592 func (p PanicF) Format(f State, c rune) {
1593 panic(p.message)
1596 var panictests = []struct {
1597 fmt string
1598 in interface{}
1599 out string
1601 // String
1602 {"%s", (*PanicS)(nil), "<nil>"}, // nil pointer special case
1603 {"%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
1604 {"%s", PanicS{3}, "%!s(PANIC=3)"},
1605 // GoString
1606 {"%#v", (*PanicGo)(nil), "<nil>"}, // nil pointer special case
1607 {"%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"},
1608 {"%#v", PanicGo{3}, "%!v(PANIC=3)"},
1609 // Issue 18282. catchPanic should not clear fmtFlags permanently.
1610 {"%#v", []interface{}{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=3), %!v(PANIC=3)}"},
1611 // Format
1612 {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
1613 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
1614 {"%s", PanicF{3}, "%!s(PANIC=3)"},
1617 func TestPanics(t *testing.T) {
1618 for i, tt := range panictests {
1619 s := Sprintf(tt.fmt, tt.in)
1620 if s != tt.out {
1621 t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
1626 // recurCount tests that erroneous String routine doesn't cause fatal recursion.
1627 var recurCount = 0
1629 type Recur struct {
1630 i int
1631 failed *bool
1634 func (r *Recur) String() string {
1635 if recurCount++; recurCount > 10 {
1636 *r.failed = true
1637 return "FAIL"
1639 // This will call badVerb. Before the fix, that would cause us to recur into
1640 // this routine to print %!p(value). Now we don't call the user's method
1641 // during an error.
1642 return Sprintf("recur@%p value: %d", r, r.i)
1645 func TestBadVerbRecursion(t *testing.T) {
1646 failed := false
1647 r := &Recur{3, &failed}
1648 Sprintf("recur@%p value: %d\n", &r, r.i)
1649 if failed {
1650 t.Error("fail with pointer")
1652 failed = false
1653 r = &Recur{4, &failed}
1654 Sprintf("recur@%p, value: %d\n", r, r.i)
1655 if failed {
1656 t.Error("fail with value")
1660 func TestIsSpace(t *testing.T) {
1661 // This tests the internal isSpace function.
1662 // IsSpace = isSpace is defined in export_test.go.
1663 for i := rune(0); i <= unicode.MaxRune; i++ {
1664 if IsSpace(i) != unicode.IsSpace(i) {
1665 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
1670 func TestNilDoesNotBecomeTyped(t *testing.T) {
1671 type A struct{}
1672 type B struct{}
1673 var a *A = nil
1674 var b B = B{}
1675 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) // go vet should complain about this line.
1676 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
1677 if got != expect {
1678 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
1682 var formatterFlagTests = []struct {
1683 in string
1684 val interface{}
1685 out string
1687 // scalar values with the (unused by fmt) 'a' verb.
1688 {"%a", flagPrinter{}, "[%a]"},
1689 {"%-a", flagPrinter{}, "[%-a]"},
1690 {"%+a", flagPrinter{}, "[%+a]"},
1691 {"%#a", flagPrinter{}, "[%#a]"},
1692 {"% a", flagPrinter{}, "[% a]"},
1693 {"%0a", flagPrinter{}, "[%0a]"},
1694 {"%1.2a", flagPrinter{}, "[%1.2a]"},
1695 {"%-1.2a", flagPrinter{}, "[%-1.2a]"},
1696 {"%+1.2a", flagPrinter{}, "[%+1.2a]"},
1697 {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
1698 {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
1699 {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
1701 // composite values with the 'a' verb
1702 {"%a", [1]flagPrinter{}, "[[%a]]"},
1703 {"%-a", [1]flagPrinter{}, "[[%-a]]"},
1704 {"%+a", [1]flagPrinter{}, "[[%+a]]"},
1705 {"%#a", [1]flagPrinter{}, "[[%#a]]"},
1706 {"% a", [1]flagPrinter{}, "[[% a]]"},
1707 {"%0a", [1]flagPrinter{}, "[[%0a]]"},
1708 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
1709 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
1710 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
1711 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
1712 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
1713 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
1715 // simple values with the 'v' verb
1716 {"%v", flagPrinter{}, "[%v]"},
1717 {"%-v", flagPrinter{}, "[%-v]"},
1718 {"%+v", flagPrinter{}, "[%+v]"},
1719 {"%#v", flagPrinter{}, "[%#v]"},
1720 {"% v", flagPrinter{}, "[% v]"},
1721 {"%0v", flagPrinter{}, "[%0v]"},
1722 {"%1.2v", flagPrinter{}, "[%1.2v]"},
1723 {"%-1.2v", flagPrinter{}, "[%-1.2v]"},
1724 {"%+1.2v", flagPrinter{}, "[%+1.2v]"},
1725 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
1726 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
1727 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
1729 // composite values with the 'v' verb.
1730 {"%v", [1]flagPrinter{}, "[[%v]]"},
1731 {"%-v", [1]flagPrinter{}, "[[%-v]]"},
1732 {"%+v", [1]flagPrinter{}, "[[%+v]]"},
1733 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"},
1734 {"% v", [1]flagPrinter{}, "[[% v]]"},
1735 {"%0v", [1]flagPrinter{}, "[[%0v]]"},
1736 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
1737 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
1738 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
1739 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
1740 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
1741 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
1744 func TestFormatterFlags(t *testing.T) {
1745 for _, tt := range formatterFlagTests {
1746 s := Sprintf(tt.in, tt.val)
1747 if s != tt.out {
1748 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out)
1753 func TestParsenum(t *testing.T) {
1754 testCases := []struct {
1755 s string
1756 start, end int
1757 num int
1758 isnum bool
1759 newi int
1761 {"a123", 0, 4, 0, false, 0},
1762 {"1234", 1, 1, 0, false, 1},
1763 {"123a", 0, 4, 123, true, 3},
1764 {"12a3", 0, 4, 12, true, 2},
1765 {"1234", 0, 4, 1234, true, 4},
1766 {"1a234", 1, 3, 0, false, 1},
1768 for _, tt := range testCases {
1769 num, isnum, newi := Parsenum(tt.s, tt.start, tt.end)
1770 if num != tt.num || isnum != tt.isnum || newi != tt.newi {
1771 t.Errorf("parsenum(%q, %d, %d) = %d, %v, %d, want %d, %v, %d", tt.s, tt.start, tt.end, num, isnum, newi, tt.num, tt.isnum, tt.newi)