Source file
src/fmt/fmt_test.go
1
2
3
4
5 package fmt_test
6
7 import (
8 "bytes"
9 . "fmt"
10 "internal/race"
11 "io"
12 "math"
13 "reflect"
14 "strings"
15 "testing"
16 "time"
17 "unicode"
18 )
19
20 type (
21 renamedBool bool
22 renamedInt int
23 renamedInt8 int8
24 renamedInt16 int16
25 renamedInt32 int32
26 renamedInt64 int64
27 renamedUint uint
28 renamedUint8 uint8
29 renamedUint16 uint16
30 renamedUint32 uint32
31 renamedUint64 uint64
32 renamedUintptr uintptr
33 renamedString string
34 renamedBytes []byte
35 renamedFloat32 float32
36 renamedFloat64 float64
37 renamedComplex64 complex64
38 renamedComplex128 complex128
39 )
40
41 func TestFmtInterface(t *testing.T) {
42 var i1 any
43 i1 = "abc"
44 s := Sprintf("%s", i1)
45 if s != "abc" {
46 t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
47 }
48 }
49
50 var (
51 NaN = math.NaN()
52 posInf = math.Inf(1)
53 negInf = math.Inf(-1)
54
55 intVar = 0
56
57 array = [5]int{1, 2, 3, 4, 5}
58 iarray = [4]any{1, "hello", 2.5, nil}
59 slice = array[:]
60 islice = iarray[:]
61 )
62
63 type A struct {
64 i int
65 j uint
66 s string
67 x []int
68 }
69
70 type I int
71
72 func (i I) String() string { return Sprintf("<%d>", int(i)) }
73
74 type B struct {
75 I I
76 j int
77 }
78
79 type C struct {
80 i int
81 B
82 }
83
84 type F int
85
86 func (f F) Format(s State, c rune) {
87 Fprintf(s, "<%c=F(%d)>", c, int(f))
88 }
89
90 type G int
91
92 func (g G) GoString() string {
93 return Sprintf("GoString(%d)", int(g))
94 }
95
96 type S struct {
97 F F
98 G G
99 }
100
101 type SI struct {
102 I any
103 }
104
105
106 type P int
107
108 var pValue P
109
110 func (p *P) String() string {
111 return "String(p)"
112 }
113
114
115 type Fn func() int
116
117 func (fn Fn) String() string { return "String(fn)" }
118
119 var fnValue Fn
120
121
122 type U struct {
123 u func() string
124 fn Fn
125 }
126
127 var barray = [5]renamedUint8{1, 2, 3, 4, 5}
128 var bslice = barray[:]
129
130 type byteStringer byte
131
132 func (byteStringer) String() string {
133 return "X"
134 }
135
136 var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'}
137
138 type byteFormatter byte
139
140 func (byteFormatter) Format(f State, _ rune) {
141 Fprint(f, "X")
142 }
143
144 var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
145
146 type writeStringFormatter string
147
148 func (sf writeStringFormatter) Format(f State, c rune) {
149 if sw, ok := f.(io.StringWriter); ok {
150 sw.WriteString("***" + string(sf) + "***")
151 }
152 }
153
154 var fmtTests = []struct {
155 fmt string
156 val any
157 out string
158 }{
159 {"%d", 12345, "12345"},
160 {"%v", 12345, "12345"},
161 {"%t", true, "true"},
162
163
164 {"%s", "abc", "abc"},
165 {"%q", "abc", `"abc"`},
166 {"%x", "abc", "616263"},
167 {"%x", "\xff\xf0\x0f\xff", "fff00fff"},
168 {"%X", "\xff\xf0\x0f\xff", "FFF00FFF"},
169 {"%x", "", ""},
170 {"% x", "", ""},
171 {"%#x", "", ""},
172 {"%# x", "", ""},
173 {"%x", "xyz", "78797a"},
174 {"%X", "xyz", "78797A"},
175 {"% x", "xyz", "78 79 7a"},
176 {"% X", "xyz", "78 79 7A"},
177 {"%#x", "xyz", "0x78797a"},
178 {"%#X", "xyz", "0X78797A"},
179 {"%# x", "xyz", "0x78 0x79 0x7a"},
180 {"%# X", "xyz", "0X78 0X79 0X7A"},
181
182
183 {"%s", []byte("abc"), "abc"},
184 {"%s", [3]byte{'a', 'b', 'c'}, "abc"},
185 {"%s", &[3]byte{'a', 'b', 'c'}, "&abc"},
186 {"%q", []byte("abc"), `"abc"`},
187 {"%x", []byte("abc"), "616263"},
188 {"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"},
189 {"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"},
190 {"%x", []byte(""), ""},
191 {"% x", []byte(""), ""},
192 {"%#x", []byte(""), ""},
193 {"%# x", []byte(""), ""},
194 {"%x", []byte("xyz"), "78797a"},
195 {"%X", []byte("xyz"), "78797A"},
196 {"% x", []byte("xyz"), "78 79 7a"},
197 {"% X", []byte("xyz"), "78 79 7A"},
198 {"%#x", []byte("xyz"), "0x78797a"},
199 {"%#X", []byte("xyz"), "0X78797A"},
200 {"%# x", []byte("xyz"), "0x78 0x79 0x7a"},
201 {"%# X", []byte("xyz"), "0X78 0X79 0X7A"},
202
203
204 {"%q", "", `""`},
205 {"%#q", "", "``"},
206 {"%q", "\"", `"\""`},
207 {"%#q", "\"", "`\"`"},
208 {"%q", "`", `"` + "`" + `"`},
209 {"%#q", "`", `"` + "`" + `"`},
210 {"%q", "\n", `"\n"`},
211 {"%#q", "\n", `"\n"`},
212 {"%q", `\n`, `"\\n"`},
213 {"%#q", `\n`, "`\\n`"},
214 {"%q", "abc", `"abc"`},
215 {"%#q", "abc", "`abc`"},
216 {"%q", "日本語", `"日本語"`},
217 {"%+q", "日本語", `"\u65e5\u672c\u8a9e"`},
218 {"%#q", "日本語", "`日本語`"},
219 {"%#+q", "日本語", "`日本語`"},
220 {"%q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
221 {"%+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
222 {"%#q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
223 {"%#+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
224 {"%q", "☺", `"☺"`},
225 {"% q", "☺", `"☺"`},
226 {"%+q", "☺", `"\u263a"`},
227 {"%#q", "☺", "`☺`"},
228 {"%#+q", "☺", "`☺`"},
229 {"%10q", "⌘", ` "⌘"`},
230 {"%+10q", "⌘", ` "\u2318"`},
231 {"%-10q", "⌘", `"⌘" `},
232 {"%+-10q", "⌘", `"\u2318" `},
233 {"%010q", "⌘", `0000000"⌘"`},
234 {"%+010q", "⌘", `00"\u2318"`},
235 {"%-010q", "⌘", `"⌘" `},
236 {"%+-010q", "⌘", `"\u2318" `},
237 {"%#8q", "\n", ` "\n"`},
238 {"%#+8q", "\r", ` "\r"`},
239 {"%#-8q", "\t", "` ` "},
240 {"%#+-8q", "\b", `"\b" `},
241 {"%q", "abc\xffdef", `"abc\xffdef"`},
242 {"%+q", "abc\xffdef", `"abc\xffdef"`},
243 {"%#q", "abc\xffdef", `"abc\xffdef"`},
244 {"%#+q", "abc\xffdef", `"abc\xffdef"`},
245
246 {"%q", "\U0010ffff", `"\U0010ffff"`},
247 {"%+q", "\U0010ffff", `"\U0010ffff"`},
248 {"%#q", "\U0010ffff", "``"},
249 {"%#+q", "\U0010ffff", "``"},
250
251 {"%q", string(rune(0x110000)), `"�"`},
252 {"%+q", string(rune(0x110000)), `"\ufffd"`},
253 {"%#q", string(rune(0x110000)), "`�`"},
254 {"%#+q", string(rune(0x110000)), "`�`"},
255
256
257 {"%c", uint('x'), "x"},
258 {"%c", 0xe4, "ä"},
259 {"%c", 0x672c, "本"},
260 {"%c", '日', "日"},
261 {"%.0c", '⌘', "⌘"},
262 {"%3c", '⌘', " ⌘"},
263 {"%-3c", '⌘', "⌘ "},
264 {"%c", uint64(0x100000000), "\ufffd"},
265
266 {"%c", '\U00000e00', "\u0e00"},
267 {"%c", '\U0010ffff', "\U0010ffff"},
268
269 {"%c", -1, "�"},
270 {"%c", 0xDC80, "�"},
271 {"%c", rune(0x110000), "�"},
272 {"%c", int64(0xFFFFFFFFF), "�"},
273 {"%c", uint64(0xFFFFFFFFF), "�"},
274
275
276 {"%q", uint(0), `'\x00'`},
277 {"%+q", uint(0), `'\x00'`},
278 {"%q", '"', `'"'`},
279 {"%+q", '"', `'"'`},
280 {"%q", '\'', `'\''`},
281 {"%+q", '\'', `'\''`},
282 {"%q", '`', "'`'"},
283 {"%+q", '`', "'`'"},
284 {"%q", 'x', `'x'`},
285 {"%+q", 'x', `'x'`},
286 {"%q", 'ÿ', `'ÿ'`},
287 {"%+q", 'ÿ', `'\u00ff'`},
288 {"%q", '\n', `'\n'`},
289 {"%+q", '\n', `'\n'`},
290 {"%q", '☺', `'☺'`},
291 {"%+q", '☺', `'\u263a'`},
292 {"% q", '☺', `'☺'`},
293 {"%.0q", '☺', `'☺'`},
294 {"%10q", '⌘', ` '⌘'`},
295 {"%+10q", '⌘', ` '\u2318'`},
296 {"%-10q", '⌘', `'⌘' `},
297 {"%+-10q", '⌘', `'\u2318' `},
298 {"%010q", '⌘', `0000000'⌘'`},
299 {"%+010q", '⌘', `00'\u2318'`},
300 {"%-010q", '⌘', `'⌘' `},
301 {"%+-010q", '⌘', `'\u2318' `},
302
303 {"%q", '\U00000e00', `'\u0e00'`},
304 {"%q", '\U0010ffff', `'\U0010ffff'`},
305
306 {"%q", int32(-1), `'�'`},
307 {"%q", 0xDC80, `'�'`},
308 {"%q", rune(0x110000), `'�'`},
309 {"%q", int64(0xFFFFFFFFF), `'�'`},
310 {"%q", uint64(0xFFFFFFFFF), `'�'`},
311
312
313 {"%5s", "abc", " abc"},
314 {"%5s", []byte("abc"), " abc"},
315 {"%2s", "\u263a", " ☺"},
316 {"%2s", []byte("\u263a"), " ☺"},
317 {"%-5s", "abc", "abc "},
318 {"%-5s", []byte("abc"), "abc "},
319 {"%05s", "abc", "00abc"},
320 {"%05s", []byte("abc"), "00abc"},
321 {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
322 {"%5s", []byte("abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz"},
323 {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
324 {"%.5s", []byte("abcdefghijklmnopqrstuvwxyz"), "abcde"},
325 {"%.0s", "日本語日本語", ""},
326 {"%.0s", []byte("日本語日本語"), ""},
327 {"%.5s", "日本語日本語", "日本語日本"},
328 {"%.5s", []byte("日本語日本語"), "日本語日本"},
329 {"%.10s", "日本語日本語", "日本語日本語"},
330 {"%.10s", []byte("日本語日本語"), "日本語日本語"},
331 {"%08q", "abc", `000"abc"`},
332 {"%08q", []byte("abc"), `000"abc"`},
333 {"%-8q", "abc", `"abc" `},
334 {"%-8q", []byte("abc"), `"abc" `},
335 {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
336 {"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
337 {"%.5x", "abcdefghijklmnopqrstuvwxyz", "6162636465"},
338 {"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), "6162636465"},
339 {"%.3q", "日本語日本語", `"日本語"`},
340 {"%.3q", []byte("日本語日本語"), `"日本語"`},
341 {"%.1q", "日本語", `"日"`},
342 {"%.1q", []byte("日本語"), `"日"`},
343 {"%.1x", "日本語", "e6"},
344 {"%.1X", []byte("日本語"), "E6"},
345 {"%10.1q", "日本語日本語", ` "日"`},
346 {"%10.1q", []byte("日本語日本語"), ` "日"`},
347 {"%10v", nil, " <nil>"},
348 {"%-10v", nil, "<nil> "},
349
350
351 {"%d", uint(12345), "12345"},
352 {"%d", int(-12345), "-12345"},
353 {"%d", ^uint8(0), "255"},
354 {"%d", ^uint16(0), "65535"},
355 {"%d", ^uint32(0), "4294967295"},
356 {"%d", ^uint64(0), "18446744073709551615"},
357 {"%d", int8(-1 << 7), "-128"},
358 {"%d", int16(-1 << 15), "-32768"},
359 {"%d", int32(-1 << 31), "-2147483648"},
360 {"%d", int64(-1 << 63), "-9223372036854775808"},
361 {"%.d", 0, ""},
362 {"%.0d", 0, ""},
363 {"%6.0d", 0, " "},
364 {"%06.0d", 0, " "},
365 {"% d", 12345, " 12345"},
366 {"%+d", 12345, "+12345"},
367 {"%+d", -12345, "-12345"},
368 {"%b", 7, "111"},
369 {"%b", -6, "-110"},
370 {"%#b", 7, "0b111"},
371 {"%#b", -6, "-0b110"},
372 {"%b", ^uint32(0), "11111111111111111111111111111111"},
373 {"%b", ^uint64(0), "1111111111111111111111111111111111111111111111111111111111111111"},
374 {"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
375 {"%o", 01234, "1234"},
376 {"%o", -01234, "-1234"},
377 {"%#o", 01234, "01234"},
378 {"%#o", -01234, "-01234"},
379 {"%O", 01234, "0o1234"},
380 {"%O", -01234, "-0o1234"},
381 {"%o", ^uint32(0), "37777777777"},
382 {"%o", ^uint64(0), "1777777777777777777777"},
383 {"%#X", 0, "0X0"},
384 {"%x", 0x12abcdef, "12abcdef"},
385 {"%X", 0x12abcdef, "12ABCDEF"},
386 {"%x", ^uint32(0), "ffffffff"},
387 {"%X", ^uint64(0), "FFFFFFFFFFFFFFFF"},
388 {"%.20b", 7, "00000000000000000111"},
389 {"%10d", 12345, " 12345"},
390 {"%10d", -12345, " -12345"},
391 {"%+10d", 12345, " +12345"},
392 {"%010d", 12345, "0000012345"},
393 {"%010d", -12345, "-000012345"},
394 {"%20.8d", 1234, " 00001234"},
395 {"%20.8d", -1234, " -00001234"},
396 {"%020.8d", 1234, " 00001234"},
397 {"%020.8d", -1234, " -00001234"},
398 {"%-20.8d", 1234, "00001234 "},
399 {"%-20.8d", -1234, "-00001234 "},
400 {"%-#20.8x", 0x1234abc, "0x01234abc "},
401 {"%-#20.8X", 0x1234abc, "0X01234ABC "},
402 {"%-#20.8o", 01234, "00001234 "},
403
404
405 {"%068d", 1, zeroFill("", 68, "1")},
406 {"%068d", -1, zeroFill("-", 67, "1")},
407 {"%#.68x", 42, zeroFill("0x", 68, "2a")},
408 {"%.68d", -42, zeroFill("-", 68, "42")},
409 {"%+.68d", 42, zeroFill("+", 68, "42")},
410 {"% .68d", 42, zeroFill(" ", 68, "42")},
411 {"% +.68d", 42, zeroFill("+", 68, "42")},
412
413
414 {"%U", 0, "U+0000"},
415 {"%U", -1, "U+FFFFFFFFFFFFFFFF"},
416 {"%U", '\n', `U+000A`},
417 {"%#U", '\n', `U+000A`},
418 {"%+U", 'x', `U+0078`},
419 {"%# U", 'x', `U+0078 'x'`},
420 {"%#.2U", 'x', `U+0078 'x'`},
421 {"%U", '\u263a', `U+263A`},
422 {"%#U", '\u263a', `U+263A '☺'`},
423 {"%U", '\U0001D6C2', `U+1D6C2`},
424 {"%#U", '\U0001D6C2', `U+1D6C2 '𝛂'`},
425 {"%#14.6U", '⌘', " U+002318 '⌘'"},
426 {"%#-14.6U", '⌘', "U+002318 '⌘' "},
427 {"%#014.6U", '⌘', " U+002318 '⌘'"},
428 {"%#-014.6U", '⌘', "U+002318 '⌘' "},
429 {"%.68U", uint(42), zeroFill("U+", 68, "2A")},
430 {"%#.68U", '日', zeroFill("U+", 68, "65E5") + " '日'"},
431
432
433 {"%+.3e", 0.0, "+0.000e+00"},
434 {"%+.3e", 1.0, "+1.000e+00"},
435 {"%+.3x", 0.0, "+0x0.000p+00"},
436 {"%+.3x", 1.0, "+0x1.000p+00"},
437 {"%+.3f", -1.0, "-1.000"},
438 {"%+.3F", -1.0, "-1.000"},
439 {"%+.3F", float32(-1.0), "-1.000"},
440 {"%+07.2f", 1.0, "+001.00"},
441 {"%+07.2f", -1.0, "-001.00"},
442 {"%-07.2f", 1.0, "1.00 "},
443 {"%-07.2f", -1.0, "-1.00 "},
444 {"%+-07.2f", 1.0, "+1.00 "},
445 {"%+-07.2f", -1.0, "-1.00 "},
446 {"%-+07.2f", 1.0, "+1.00 "},
447 {"%-+07.2f", -1.0, "-1.00 "},
448 {"%+10.2f", +1.0, " +1.00"},
449 {"%+10.2f", -1.0, " -1.00"},
450 {"% .3E", -1.0, "-1.000E+00"},
451 {"% .3e", 1.0, " 1.000e+00"},
452 {"% .3X", -1.0, "-0X1.000P+00"},
453 {"% .3x", 1.0, " 0x1.000p+00"},
454 {"%+.3g", 0.0, "+0"},
455 {"%+.3g", 1.0, "+1"},
456 {"%+.3g", -1.0, "-1"},
457 {"% .3g", -1.0, "-1"},
458 {"% .3g", 1.0, " 1"},
459 {"%b", float32(1.0), "8388608p-23"},
460 {"%b", 1.0, "4503599627370496p-52"},
461
462 {"%#g", 1e-323, "1.00000e-323"},
463 {"%#g", -1.0, "-1.00000"},
464 {"%#g", 1.1, "1.10000"},
465 {"%#g", 123456.0, "123456."},
466 {"%#g", 1234567.0, "1.234567e+06"},
467 {"%#g", 1230000.0, "1.23000e+06"},
468 {"%#g", 1000000.0, "1.00000e+06"},
469 {"%#.0f", 1.0, "1."},
470 {"%#.0e", 1.0, "1.e+00"},
471 {"%#.0x", 1.0, "0x1.p+00"},
472 {"%#.0g", 1.0, "1."},
473 {"%#.0g", 1100000.0, "1.e+06"},
474 {"%#.4f", 1.0, "1.0000"},
475 {"%#.4e", 1.0, "1.0000e+00"},
476 {"%#.4x", 1.0, "0x1.0000p+00"},
477 {"%#.4g", 1.0, "1.000"},
478 {"%#.4g", 100000.0, "1.000e+05"},
479 {"%#.4g", 1.234, "1.234"},
480 {"%#.4g", 0.1234, "0.1234"},
481 {"%#.4g", 1.23, "1.230"},
482 {"%#.4g", 0.123, "0.1230"},
483 {"%#.4g", 1.2, "1.200"},
484 {"%#.4g", 0.12, "0.1200"},
485 {"%#.4g", 10.2, "10.20"},
486 {"%#.4g", 0.0, "0.000"},
487 {"%#.4g", 0.012, "0.01200"},
488 {"%#.0f", 123.0, "123."},
489 {"%#.0e", 123.0, "1.e+02"},
490 {"%#.0x", 123.0, "0x1.p+07"},
491 {"%#.0g", 123.0, "1.e+02"},
492 {"%#.4f", 123.0, "123.0000"},
493 {"%#.4e", 123.0, "1.2300e+02"},
494 {"%#.4x", 123.0, "0x1.ec00p+06"},
495 {"%#.4g", 123.0, "123.0"},
496 {"%#.4g", 123000.0, "1.230e+05"},
497 {"%#9.4g", 1.0, " 1.000"},
498
499 {"%#b", 1.0, "4503599627370496p-52"},
500
501 {"%.4b", float32(1.0), "8388608p-23"},
502 {"%.4b", -1.0, "-4503599627370496p-52"},
503
504 {"%.68f", 1.0, zeroFill("1.", 68, "")},
505 {"%.68f", -1.0, zeroFill("-1.", 68, "")},
506
507 {"%f", posInf, "+Inf"},
508 {"%.1f", negInf, "-Inf"},
509 {"% f", NaN, " NaN"},
510 {"%20f", posInf, " +Inf"},
511 {"% 20F", posInf, " Inf"},
512 {"% 20e", negInf, " -Inf"},
513 {"% 20x", negInf, " -Inf"},
514 {"%+20E", negInf, " -Inf"},
515 {"%+20X", negInf, " -Inf"},
516 {"% +20g", negInf, " -Inf"},
517 {"%+-20G", posInf, "+Inf "},
518 {"%20e", NaN, " NaN"},
519 {"%20x", NaN, " NaN"},
520 {"% +20E", NaN, " +NaN"},
521 {"% +20X", NaN, " +NaN"},
522 {"% -20g", NaN, " NaN "},
523 {"%+-20G", NaN, "+NaN "},
524
525 {"%+020e", posInf, " +Inf"},
526 {"%+020x", posInf, " +Inf"},
527 {"%-020f", negInf, "-Inf "},
528 {"%-020E", NaN, "NaN "},
529 {"%-020X", NaN, "NaN "},
530
531
532 {"%.f", 0i, "(0+0i)"},
533 {"% .f", 0i, "( 0+0i)"},
534 {"%+.f", 0i, "(+0+0i)"},
535 {"% +.f", 0i, "(+0+0i)"},
536 {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
537 {"%+.3x", 0i, "(+0x0.000p+00+0x0.000p+00i)"},
538 {"%+.3f", 0i, "(+0.000+0.000i)"},
539 {"%+.3g", 0i, "(+0+0i)"},
540 {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
541 {"%+.3x", 1 + 2i, "(+0x1.000p+00+0x1.000p+01i)"},
542 {"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
543 {"%+.3g", 1 + 2i, "(+1+2i)"},
544 {"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
545 {"%.3x", 0i, "(0x0.000p+00+0x0.000p+00i)"},
546 {"%.3f", 0i, "(0.000+0.000i)"},
547 {"%.3F", 0i, "(0.000+0.000i)"},
548 {"%.3F", complex64(0i), "(0.000+0.000i)"},
549 {"%.3g", 0i, "(0+0i)"},
550 {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
551 {"%.3x", 1 + 2i, "(0x1.000p+00+0x1.000p+01i)"},
552 {"%.3f", 1 + 2i, "(1.000+2.000i)"},
553 {"%.3g", 1 + 2i, "(1+2i)"},
554 {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
555 {"%.3x", -1 - 2i, "(-0x1.000p+00-0x1.000p+01i)"},
556 {"%.3f", -1 - 2i, "(-1.000-2.000i)"},
557 {"%.3g", -1 - 2i, "(-1-2i)"},
558 {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
559 {"% .3X", -1 - 2i, "(-0X1.000P+00-0X1.000P+01i)"},
560 {"%+.3g", 1 + 2i, "(+1+2i)"},
561 {"%+.3g", complex64(1 + 2i), "(+1+2i)"},
562 {"%#g", 1 + 2i, "(1.00000+2.00000i)"},
563 {"%#g", 123456 + 789012i, "(123456.+789012.i)"},
564 {"%#g", 1e-10i, "(0.00000+1.00000e-10i)"},
565 {"%#g", -1e10 - 1.11e100i, "(-1.00000e+10-1.11000e+100i)"},
566 {"%#.0f", 1.23 + 1.0i, "(1.+1.i)"},
567 {"%#.0e", 1.23 + 1.0i, "(1.e+00+1.e+00i)"},
568 {"%#.0x", 1.23 + 1.0i, "(0x1.p+00+0x1.p+00i)"},
569 {"%#.0g", 1.23 + 1.0i, "(1.+1.i)"},
570 {"%#.0g", 0 + 100000i, "(0.+1.e+05i)"},
571 {"%#.0g", 1230000 + 0i, "(1.e+06+0.i)"},
572 {"%#.4f", 1 + 1.23i, "(1.0000+1.2300i)"},
573 {"%#.4e", 123 + 1i, "(1.2300e+02+1.0000e+00i)"},
574 {"%#.4x", 123 + 1i, "(0x1.ec00p+06+0x1.0000p+00i)"},
575 {"%#.4g", 123 + 1.23i, "(123.0+1.230i)"},
576 {"%#12.5g", 0 + 100000i, "( 0.0000 +1.0000e+05i)"},
577 {"%#12.5g", 1230000 - 0i, "( 1.2300e+06 +0.0000i)"},
578 {"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
579 {"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
580
581 {"%#b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
582
583 {"%.4b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
584 {"%.4b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
585
586 {"%f", complex(posInf, posInf), "(+Inf+Infi)"},
587 {"%f", complex(negInf, negInf), "(-Inf-Infi)"},
588 {"%f", complex(NaN, NaN), "(NaN+NaNi)"},
589 {"%.1f", complex(posInf, posInf), "(+Inf+Infi)"},
590 {"% f", complex(posInf, posInf), "( Inf+Infi)"},
591 {"% f", complex(negInf, negInf), "(-Inf-Infi)"},
592 {"% f", complex(NaN, NaN), "( NaN+NaNi)"},
593 {"%8e", complex(posInf, posInf), "( +Inf +Infi)"},
594 {"%8x", complex(posInf, posInf), "( +Inf +Infi)"},
595 {"% 8E", complex(posInf, posInf), "( Inf +Infi)"},
596 {"% 8X", complex(posInf, posInf), "( Inf +Infi)"},
597 {"%+8f", complex(negInf, negInf), "( -Inf -Infi)"},
598 {"% +8g", complex(negInf, negInf), "( -Inf -Infi)"},
599 {"% -8G", complex(NaN, NaN), "( NaN +NaN i)"},
600 {"%+-8b", complex(NaN, NaN), "(+NaN +NaN i)"},
601
602 {"%08f", complex(posInf, posInf), "( +Inf +Infi)"},
603 {"%-08g", complex(negInf, negInf), "(-Inf -Inf i)"},
604 {"%-08G", complex(NaN, NaN), "(NaN +NaN i)"},
605
606
607 {"%e", 1.0, "1.000000e+00"},
608 {"%e", 1234.5678e3, "1.234568e+06"},
609 {"%e", 1234.5678e-8, "1.234568e-05"},
610 {"%e", -7.0, "-7.000000e+00"},
611 {"%e", -1e-9, "-1.000000e-09"},
612 {"%f", 1234.5678e3, "1234567.800000"},
613 {"%f", 1234.5678e-8, "0.000012"},
614 {"%f", -7.0, "-7.000000"},
615 {"%f", -1e-9, "-0.000000"},
616 {"%g", 1234.5678e3, "1.2345678e+06"},
617 {"%g", float32(1234.5678e3), "1.2345678e+06"},
618 {"%g", 1234.5678e-8, "1.2345678e-05"},
619 {"%g", -7.0, "-7"},
620 {"%g", -1e-9, "-1e-09"},
621 {"%g", float32(-1e-9), "-1e-09"},
622 {"%E", 1.0, "1.000000E+00"},
623 {"%E", 1234.5678e3, "1.234568E+06"},
624 {"%E", 1234.5678e-8, "1.234568E-05"},
625 {"%E", -7.0, "-7.000000E+00"},
626 {"%E", -1e-9, "-1.000000E-09"},
627 {"%G", 1234.5678e3, "1.2345678E+06"},
628 {"%G", float32(1234.5678e3), "1.2345678E+06"},
629 {"%G", 1234.5678e-8, "1.2345678E-05"},
630 {"%G", -7.0, "-7"},
631 {"%G", -1e-9, "-1E-09"},
632 {"%G", float32(-1e-9), "-1E-09"},
633 {"%20.5s", "qwertyuiop", " qwert"},
634 {"%.5s", "qwertyuiop", "qwert"},
635 {"%-20.5s", "qwertyuiop", "qwert "},
636 {"%20c", 'x', " x"},
637 {"%-20c", 'x', "x "},
638 {"%20.6e", 1.2345e3, " 1.234500e+03"},
639 {"%20.6e", 1.2345e-3, " 1.234500e-03"},
640 {"%20e", 1.2345e3, " 1.234500e+03"},
641 {"%20e", 1.2345e-3, " 1.234500e-03"},
642 {"%20.8e", 1.2345e3, " 1.23450000e+03"},
643 {"%20f", 1.23456789e3, " 1234.567890"},
644 {"%20f", 1.23456789e-3, " 0.001235"},
645 {"%20f", 12345678901.23456789, " 12345678901.234568"},
646 {"%-20f", 1.23456789e3, "1234.567890 "},
647 {"%20.8f", 1.23456789e3, " 1234.56789000"},
648 {"%20.8f", 1.23456789e-3, " 0.00123457"},
649 {"%g", 1.23456789e3, "1234.56789"},
650 {"%g", 1.23456789e-3, "0.00123456789"},
651 {"%g", 1.23456789e20, "1.23456789e+20"},
652
653
654 {"%v", array, "[1 2 3 4 5]"},
655 {"%v", iarray, "[1 hello 2.5 <nil>]"},
656 {"%v", barray, "[1 2 3 4 5]"},
657 {"%v", &array, "&[1 2 3 4 5]"},
658 {"%v", &iarray, "&[1 hello 2.5 <nil>]"},
659 {"%v", &barray, "&[1 2 3 4 5]"},
660
661
662 {"%v", slice, "[1 2 3 4 5]"},
663 {"%v", islice, "[1 hello 2.5 <nil>]"},
664 {"%v", bslice, "[1 2 3 4 5]"},
665 {"%v", &slice, "&[1 2 3 4 5]"},
666 {"%v", &islice, "&[1 hello 2.5 <nil>]"},
667 {"%v", &bslice, "&[1 2 3 4 5]"},
668
669
670 {"%b", [3]byte{65, 66, 67}, "[1000001 1000010 1000011]"},
671 {"%c", [3]byte{65, 66, 67}, "[A B C]"},
672 {"%d", [3]byte{65, 66, 67}, "[65 66 67]"},
673 {"%o", [3]byte{65, 66, 67}, "[101 102 103]"},
674 {"%U", [3]byte{65, 66, 67}, "[U+0041 U+0042 U+0043]"},
675 {"%v", [3]byte{65, 66, 67}, "[65 66 67]"},
676 {"%v", [1]byte{123}, "[123]"},
677 {"%012v", []byte{}, "[]"},
678 {"%#012v", []byte{}, "[]byte{}"},
679 {"%6v", []byte{1, 11, 111}, "[ 1 11 111]"},
680 {"%06v", []byte{1, 11, 111}, "[000001 000011 000111]"},
681 {"%-6v", []byte{1, 11, 111}, "[1 11 111 ]"},
682 {"%-06v", []byte{1, 11, 111}, "[1 11 111 ]"},
683 {"%#v", []byte{1, 11, 111}, "[]byte{0x1, 0xb, 0x6f}"},
684 {"%#6v", []byte{1, 11, 111}, "[]byte{ 0x1, 0xb, 0x6f}"},
685 {"%#06v", []byte{1, 11, 111}, "[]byte{0x000001, 0x00000b, 0x00006f}"},
686 {"%#-6v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
687 {"%#-06v", []byte{1, 11, 111}, "[]byte{0x1 , 0xb , 0x6f }"},
688
689 {"% v", []byte{1, 11, 111}, "[ 1 11 111]"},
690 {"%+v", [3]byte{1, 11, 111}, "[1 11 111]"},
691 {"%# -6v", []byte{1, 11, 111}, "[]byte{ 0x1 , 0xb , 0x6f }"},
692 {"%#+-6v", [3]byte{1, 11, 111}, "[3]uint8{0x1 , 0xb , 0x6f }"},
693
694 {"% d", []byte{1, 11, 111}, "[ 1 11 111]"},
695 {"%+d", [3]byte{1, 11, 111}, "[+1 +11 +111]"},
696 {"%# -6d", []byte{1, 11, 111}, "[ 1 11 111 ]"},
697 {"%#+-6d", [3]byte{1, 11, 111}, "[+1 +11 +111 ]"},
698
699
700 {"%v", 1.2345678, "1.2345678"},
701 {"%v", float32(1.2345678), "1.2345678"},
702
703
704 {"%v", 1 + 2i, "(1+2i)"},
705 {"%v", complex64(1 + 2i), "(1+2i)"},
706
707
708 {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
709 {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
710
711
712 {"%+v", B{1, 2}, `{I:<1> j:2}`},
713 {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
714
715
716 {"%s", I(23), `<23>`},
717 {"%q", I(23), `"<23>"`},
718 {"%x", I(23), `3c32333e`},
719 {"%#x", I(23), `0x3c32333e`},
720 {"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
721
722 {"%d", I(23), `23`},
723
724 {"%s", reflect.ValueOf(I(23)), `<23>`},
725
726
727 {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
728 {"%#v", new(byte), "(*uint8)(0xPTR)"},
729 {"%#v", make(chan int), "(chan int)(0xPTR)"},
730 {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
731 {"%#v", 1000000000, "1000000000"},
732 {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
733 {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
734 {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
735 {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
736 {"%#v", []int(nil), `[]int(nil)`},
737 {"%#v", []int{}, `[]int{}`},
738 {"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
739 {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
740 {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
741 {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
742 {"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
743 {"%#v", map[int]byte{}, `map[int]uint8{}`},
744 {"%#v", "foo", `"foo"`},
745 {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
746 {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
747 {"%#v", []int32(nil), "[]int32(nil)"},
748 {"%#v", 1.2345678, "1.2345678"},
749 {"%#v", float32(1.2345678), "1.2345678"},
750
751
752 {"%v", TestFmtInterface, "0xPTR"},
753 {"%v", reflect.ValueOf(TestFmtInterface), "0xPTR"},
754 {"%v", G.GoString, "0xPTR"},
755 {"%v", reflect.ValueOf(G.GoString), "0xPTR"},
756 {"%v", G(23).GoString, "0xPTR"},
757 {"%v", reflect.ValueOf(G(23).GoString), "0xPTR"},
758 {"%v", reflect.ValueOf(G(23)).Method(0), "0xPTR"},
759 {"%v", Fn.String, "0xPTR"},
760 {"%v", reflect.ValueOf(Fn.String), "0xPTR"},
761 {"%v", fnValue, "String(fn)"},
762 {"%v", reflect.ValueOf(fnValue), "String(fn)"},
763 {"%v", [1]Fn{fnValue}, "[String(fn)]"},
764 {"%v", reflect.ValueOf([1]Fn{fnValue}), "[String(fn)]"},
765 {"%v", fnValue.String, "0xPTR"},
766 {"%v", reflect.ValueOf(fnValue.String), "0xPTR"},
767 {"%v", reflect.ValueOf(fnValue).Method(0), "0xPTR"},
768 {"%v", U{}.u, "<nil>"},
769 {"%v", reflect.ValueOf(U{}.u), "<nil>"},
770 {"%v", reflect.ValueOf(U{}).Field(0), "<nil>"},
771 {"%v", U{fn: fnValue}.fn, "String(fn)"},
772 {"%v", reflect.ValueOf(U{fn: fnValue}.fn), "String(fn)"},
773 {"%v", reflect.ValueOf(U{fn: fnValue}).Field(1), "<nil>"},
774
775
776 {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
777 {"%#v", reflect.ValueOf(TestFmtInterface), "(func(*testing.T))(0xPTR)"},
778 {"%#v", G.GoString, "(func(fmt_test.G) string)(0xPTR)"},
779 {"%#v", reflect.ValueOf(G.GoString), "(func(fmt_test.G) string)(0xPTR)"},
780 {"%#v", G(23).GoString, "(func() string)(0xPTR)"},
781 {"%#v", reflect.ValueOf(G(23).GoString), "(func() string)(0xPTR)"},
782 {"%#v", reflect.ValueOf(G(23)).Method(0), "(func() string)(0xPTR)"},
783 {"%#v", Fn.String, "(func(fmt_test.Fn) string)(0xPTR)"},
784 {"%#v", reflect.ValueOf(Fn.String), "(func(fmt_test.Fn) string)(0xPTR)"},
785 {"%#v", fnValue, "(fmt_test.Fn)(nil)"},
786 {"%#v", reflect.ValueOf(fnValue), "(fmt_test.Fn)(nil)"},
787 {"%#v", [1]Fn{fnValue}, "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}"},
788 {"%#v", reflect.ValueOf([1]Fn{fnValue}), "[1]fmt_test.Fn{(fmt_test.Fn)(nil)}"},
789 {"%#v", fnValue.String, "(func() string)(0xPTR)"},
790 {"%#v", reflect.ValueOf(fnValue.String), "(func() string)(0xPTR)"},
791 {"%#v", reflect.ValueOf(fnValue).Method(0), "(func() string)(0xPTR)"},
792 {"%#v", U{}.u, "(func() string)(nil)"},
793 {"%#v", reflect.ValueOf(U{}.u), "(func() string)(nil)"},
794 {"%#v", reflect.ValueOf(U{}).Field(0), "(func() string)(nil)"},
795 {"%#v", U{fn: fnValue}.fn, "(fmt_test.Fn)(nil)"},
796 {"%#v", reflect.ValueOf(U{fn: fnValue}.fn), "(fmt_test.Fn)(nil)"},
797 {"%#v", reflect.ValueOf(U{fn: fnValue}).Field(1), "(fmt_test.Fn)(nil)"},
798
799
800 {"%#v", 1.0, "1"},
801 {"%#v", 1000000.0, "1e+06"},
802 {"%#v", float32(1.0), "1"},
803 {"%#v", float32(1000000.0), "1e+06"},
804
805
806 {"%#v", []byte(nil), "[]byte(nil)"},
807 {"%#v", []uint8(nil), "[]byte(nil)"},
808 {"%#v", []byte{}, "[]byte{}"},
809 {"%#v", []uint8{}, "[]byte{}"},
810 {"%#v", reflect.ValueOf([]byte{}), "[]uint8{}"},
811 {"%#v", reflect.ValueOf([]uint8{}), "[]uint8{}"},
812 {"%#v", &[]byte{}, "&[]uint8{}"},
813 {"%#v", &[]byte{}, "&[]uint8{}"},
814 {"%#v", [3]byte{}, "[3]uint8{0x0, 0x0, 0x0}"},
815 {"%#v", [3]uint8{}, "[3]uint8{0x0, 0x0, 0x0}"},
816
817
818 {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
819 {"%x", []int{1, 2, 15}, `[1 2 f]`},
820 {"%d", []int{1, 2, 15}, `[1 2 15]`},
821 {"%d", []byte{1, 2, 15}, `[1 2 15]`},
822 {"%q", []string{"a", "b"}, `["a" "b"]`},
823 {"% 02x", []byte{1}, "01"},
824 {"% 02x", []byte{1, 2, 3}, "01 02 03"},
825
826
827 {"%2x", []byte{}, " "},
828 {"%#2x", []byte{}, " "},
829 {"% 02x", []byte{}, "00"},
830 {"%# 02x", []byte{}, "00"},
831 {"%-2x", []byte{}, " "},
832 {"%-02x", []byte{}, " "},
833 {"%8x", []byte{0xab}, " ab"},
834 {"% 8x", []byte{0xab}, " ab"},
835 {"%#8x", []byte{0xab}, " 0xab"},
836 {"%# 8x", []byte{0xab}, " 0xab"},
837 {"%08x", []byte{0xab}, "000000ab"},
838 {"% 08x", []byte{0xab}, "000000ab"},
839 {"%#08x", []byte{0xab}, "00000xab"},
840 {"%# 08x", []byte{0xab}, "00000xab"},
841 {"%10x", []byte{0xab, 0xcd}, " abcd"},
842 {"% 10x", []byte{0xab, 0xcd}, " ab cd"},
843 {"%#10x", []byte{0xab, 0xcd}, " 0xabcd"},
844 {"%# 10x", []byte{0xab, 0xcd}, " 0xab 0xcd"},
845 {"%010x", []byte{0xab, 0xcd}, "000000abcd"},
846 {"% 010x", []byte{0xab, 0xcd}, "00000ab cd"},
847 {"%#010x", []byte{0xab, 0xcd}, "00000xabcd"},
848 {"%# 010x", []byte{0xab, 0xcd}, "00xab 0xcd"},
849 {"%-10X", []byte{0xab}, "AB "},
850 {"% -010X", []byte{0xab}, "AB "},
851 {"%#-10X", []byte{0xab, 0xcd}, "0XABCD "},
852 {"%# -010X", []byte{0xab, 0xcd}, "0XAB 0XCD "},
853
854 {"%2x", "", " "},
855 {"%#2x", "", " "},
856 {"% 02x", "", "00"},
857 {"%# 02x", "", "00"},
858 {"%-2x", "", " "},
859 {"%-02x", "", " "},
860 {"%8x", "\xab", " ab"},
861 {"% 8x", "\xab", " ab"},
862 {"%#8x", "\xab", " 0xab"},
863 {"%# 8x", "\xab", " 0xab"},
864 {"%08x", "\xab", "000000ab"},
865 {"% 08x", "\xab", "000000ab"},
866 {"%#08x", "\xab", "00000xab"},
867 {"%# 08x", "\xab", "00000xab"},
868 {"%10x", "\xab\xcd", " abcd"},
869 {"% 10x", "\xab\xcd", " ab cd"},
870 {"%#10x", "\xab\xcd", " 0xabcd"},
871 {"%# 10x", "\xab\xcd", " 0xab 0xcd"},
872 {"%010x", "\xab\xcd", "000000abcd"},
873 {"% 010x", "\xab\xcd", "00000ab cd"},
874 {"%#010x", "\xab\xcd", "00000xabcd"},
875 {"%# 010x", "\xab\xcd", "00xab 0xcd"},
876 {"%-10X", "\xab", "AB "},
877 {"% -010X", "\xab", "AB "},
878 {"%#-10X", "\xab\xcd", "0XABCD "},
879 {"%# -010X", "\xab\xcd", "0XAB 0XCD "},
880
881
882 {"%v", renamedBool(true), "true"},
883 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
884 {"%o", renamedInt(8), "10"},
885 {"%d", renamedInt8(-9), "-9"},
886 {"%v", renamedInt16(10), "10"},
887 {"%v", renamedInt32(-11), "-11"},
888 {"%X", renamedInt64(255), "FF"},
889 {"%v", renamedUint(13), "13"},
890 {"%o", renamedUint8(14), "16"},
891 {"%X", renamedUint16(15), "F"},
892 {"%d", renamedUint32(16), "16"},
893 {"%X", renamedUint64(17), "11"},
894 {"%o", renamedUintptr(18), "22"},
895 {"%x", renamedString("thing"), "7468696e67"},
896 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
897 {"%q", renamedBytes([]byte("hello")), `"hello"`},
898 {"%x", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656c6c6f"},
899 {"%X", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656C6C6F"},
900 {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
901 {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
902 {"%v", renamedFloat32(22), "22"},
903 {"%v", renamedFloat64(33), "33"},
904 {"%v", renamedComplex64(3 + 4i), "(3+4i)"},
905 {"%v", renamedComplex128(4 - 3i), "(4-3i)"},
906
907
908 {"%x", F(1), "<x=F(1)>"},
909 {"%x", G(2), "2"},
910 {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
911
912
913 {"%#v", G(6), "GoString(6)"},
914 {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
915
916
917 {"%T", byte(0), "uint8"},
918 {"%T", reflect.ValueOf(nil), "reflect.Value"},
919 {"%T", (4 - 3i), "complex128"},
920 {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
921 {"%T", intVar, "int"},
922 {"%6T", &intVar, " *int"},
923 {"%10T", nil, " <nil>"},
924 {"%-10T", nil, "<nil> "},
925
926
927 {"%p", (*int)(nil), "0x0"},
928 {"%#p", (*int)(nil), "0"},
929 {"%p", &intVar, "0xPTR"},
930 {"%#p", &intVar, "PTR"},
931 {"%p", &array, "0xPTR"},
932 {"%p", &slice, "0xPTR"},
933 {"%8.2p", (*int)(nil), " 0x00"},
934 {"%-20.16p", &intVar, "0xPTR "},
935
936 {"%p", make(chan int), "0xPTR"},
937 {"%p", make(map[int]int), "0xPTR"},
938 {"%p", func() {}, "0xPTR"},
939 {"%p", 27, "%!p(int=27)"},
940 {"%p", nil, "%!p(<nil>)"},
941 {"%#p", nil, "%!p(<nil>)"},
942
943 {"%b", &intVar, "PTR_b"},
944 {"%d", &intVar, "PTR_d"},
945 {"%o", &intVar, "PTR_o"},
946 {"%x", &intVar, "PTR_x"},
947 {"%X", &intVar, "PTR_X"},
948
949 {"%v", nil, "<nil>"},
950 {"%#v", nil, "<nil>"},
951 {"%v", (*int)(nil), "<nil>"},
952 {"%#v", (*int)(nil), "(*int)(nil)"},
953 {"%v", &intVar, "0xPTR"},
954 {"%#v", &intVar, "(*int)(0xPTR)"},
955 {"%8.2v", (*int)(nil), " <nil>"},
956 {"%-20.16v", &intVar, "0xPTR "},
957
958 {"%s", &pValue, "String(p)"},
959 {"%p", &pValue, "0xPTR"},
960
961
962 {"%s", time.Time{}.Month(), "January"},
963 {"%d", time.Time{}.Month(), "1"},
964
965
966 {"", nil, "%!(EXTRA <nil>)"},
967 {"", 2, "%!(EXTRA int=2)"},
968 {"no args", "hello", "no args%!(EXTRA string=hello)"},
969 {"%s %", "hello", "hello %!(NOVERB)"},
970 {"%s %.2", "hello", "hello %!(NOVERB)"},
971 {"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)%!(EXTRA int=0)"},
972 {"%184467440737095516170v", 0, "%!(NOVERB)%!(EXTRA int=0)"},
973
974 {"%010.2", "12345", "%!(NOVERB)%!(EXTRA string=12345)"},
975
976
977 {"%v", map[float64]int{NaN: 1, NaN: 1}, "map[NaN:1 NaN:1]"},
978
979
980
1023 {"%.2f", 1.0, "1.00"},
1024 {"%.2f", -1.0, "-1.00"},
1025 {"% .2f", 1.0, " 1.00"},
1026 {"% .2f", -1.0, "-1.00"},
1027 {"%+.2f", 1.0, "+1.00"},
1028 {"%+.2f", -1.0, "-1.00"},
1029 {"%7.2f", 1.0, " 1.00"},
1030 {"%7.2f", -1.0, " -1.00"},
1031 {"% 7.2f", 1.0, " 1.00"},
1032 {"% 7.2f", -1.0, " -1.00"},
1033 {"%+7.2f", 1.0, " +1.00"},
1034 {"%+7.2f", -1.0, " -1.00"},
1035 {"% +7.2f", 1.0, " +1.00"},
1036 {"% +7.2f", -1.0, " -1.00"},
1037 {"%07.2f", 1.0, "0001.00"},
1038 {"%07.2f", -1.0, "-001.00"},
1039 {"% 07.2f", 1.0, " 001.00"},
1040 {"% 07.2f", -1.0, "-001.00"},
1041 {"%+07.2f", 1.0, "+001.00"},
1042 {"%+07.2f", -1.0, "-001.00"},
1043 {"% +07.2f", 1.0, "+001.00"},
1044 {"% +07.2f", -1.0, "-001.00"},
1045
1046
1047 {"%7.2f", 1 + 2i, "( 1.00 +2.00i)"},
1048 {"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
1049
1050
1051 {"%0-5s", "abc", "abc "},
1052 {"%-05.1f", 1.0, "1.0 "},
1053
1054
1055
1056 {"%06v", []any{+10.0, 10}, "[000010 000010]"},
1057 {"%06v", []any{-10.0, 10}, "[-00010 000010]"},
1058 {"%06v", []any{+10.0 + 10i, 10}, "[(000010+00010i) 000010]"},
1059 {"%06v", []any{-10.0 + 10i, 10}, "[(-00010+00010i) 000010]"},
1060
1061
1062 {"%03.6v", []any{1, 2.0, "x"}, "[000001 002 00x]"},
1063 {"%03.0v", []any{0, 2.0, "x"}, "[ 002 000]"},
1064
1065
1066
1067 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
1068 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
1069
1070
1071 {"%.", 3, "%!.(int=3)"},
1072
1073
1074 {"%+10.2f", +104.66 + 440.51i, "( +104.66 +440.51i)"},
1075 {"%+10.2f", -104.66 + 440.51i, "( -104.66 +440.51i)"},
1076 {"%+10.2f", +104.66 - 440.51i, "( +104.66 -440.51i)"},
1077 {"%+10.2f", -104.66 - 440.51i, "( -104.66 -440.51i)"},
1078 {"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"},
1079 {"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"},
1080 {"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"},
1081 {"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
1082
1083
1084 {"%v", byteStringerSlice, "[X X X X X]"},
1085 {"%s", byteStringerSlice, "hello"},
1086 {"%q", byteStringerSlice, "\"hello\""},
1087 {"%x", byteStringerSlice, "68656c6c6f"},
1088 {"%X", byteStringerSlice, "68656C6C6F"},
1089 {"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x68, 0x65, 0x6c, 0x6c, 0x6f}"},
1090
1091
1092 {"%v", byteFormatterSlice, "[X X X X X]"},
1093 {"%s", byteFormatterSlice, "hello"},
1094 {"%q", byteFormatterSlice, "\"hello\""},
1095 {"%x", byteFormatterSlice, "68656c6c6f"},
1096 {"%X", byteFormatterSlice, "68656C6C6F"},
1097
1098 {"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X, X}"},
1099
1100
1101 {"%s", writeStringFormatter(""), "******"},
1102 {"%s", writeStringFormatter("xyz"), "***xyz***"},
1103 {"%s", writeStringFormatter("⌘/⌘"), "***⌘/⌘***"},
1104
1105
1106
1107
1108 {"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"},
1109 {"%v", reflect.ValueOf(A{}).Field(0), "0"},
1110
1111
1112 {"%s", reflect.ValueOf("hello"), "hello"},
1113 {"%q", reflect.ValueOf("hello"), `"hello"`},
1114 {"%#04x", reflect.ValueOf(256), "0x0100"},
1115
1116
1117 {"%v", reflect.Value{}, "<invalid reflect.Value>"},
1118 {"%v", &reflect.Value{}, "<invalid Value>"},
1119 {"%v", SI{reflect.Value{}}, "{<invalid Value>}"},
1120
1121
1122 {"%☠", nil, "%!☠(<nil>)"},
1123 {"%☠", any(nil), "%!☠(<nil>)"},
1124 {"%☠", int(0), "%!☠(int=0)"},
1125 {"%☠", uint(0), "%!☠(uint=0)"},
1126 {"%☠", []byte{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
1127 {"%☠", []uint8{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
1128 {"%☠", [1]byte{0}, "[%!☠(uint8=0)]"},
1129 {"%☠", [1]uint8{0}, "[%!☠(uint8=0)]"},
1130 {"%☠", "hello", "%!☠(string=hello)"},
1131 {"%☠", 1.2345678, "%!☠(float64=1.2345678)"},
1132 {"%☠", float32(1.2345678), "%!☠(float32=1.2345678)"},
1133 {"%☠", 1.2345678 + 1.2345678i, "%!☠(complex128=(1.2345678+1.2345678i))"},
1134 {"%☠", complex64(1.2345678 + 1.2345678i), "%!☠(complex64=(1.2345678+1.2345678i))"},
1135 {"%☠", &intVar, "%!☠(*int=0xPTR)"},
1136 {"%☠", make(chan int), "%!☠(chan int=0xPTR)"},
1137 {"%☠", func() {}, "%!☠(func()=0xPTR)"},
1138 {"%☠", reflect.ValueOf(renamedInt(0)), "%!☠(fmt_test.renamedInt=0)"},
1139 {"%☠", SI{renamedInt(0)}, "{%!☠(fmt_test.renamedInt=0)}"},
1140 {"%☠", &[]any{I(1), G(2)}, "&[%!☠(fmt_test.I=1) %!☠(fmt_test.G=2)]"},
1141 {"%☠", SI{&[]any{I(1), G(2)}}, "{%!☠(*[]interface {}=&[1 2])}"},
1142 {"%☠", reflect.Value{}, "<invalid reflect.Value>"},
1143 {"%☠", map[float64]int{NaN: 1}, "map[%!☠(float64=NaN):%!☠(int=1)]"},
1144 }
1145
1146
1147
1148 func zeroFill(prefix string, width int, suffix string) string {
1149 return prefix + strings.Repeat("0", width-len(suffix)) + suffix
1150 }
1151
1152 func TestSprintf(t *testing.T) {
1153 for _, tt := range fmtTests {
1154 s := Sprintf(tt.fmt, tt.val)
1155 i := strings.Index(tt.out, "PTR")
1156 if i >= 0 && i < len(s) {
1157 var pattern, chars string
1158 switch {
1159 case strings.HasPrefix(tt.out[i:], "PTR_b"):
1160 pattern = "PTR_b"
1161 chars = "01"
1162 case strings.HasPrefix(tt.out[i:], "PTR_o"):
1163 pattern = "PTR_o"
1164 chars = "01234567"
1165 case strings.HasPrefix(tt.out[i:], "PTR_d"):
1166 pattern = "PTR_d"
1167 chars = "0123456789"
1168 case strings.HasPrefix(tt.out[i:], "PTR_x"):
1169 pattern = "PTR_x"
1170 chars = "0123456789abcdef"
1171 case strings.HasPrefix(tt.out[i:], "PTR_X"):
1172 pattern = "PTR_X"
1173 chars = "0123456789ABCDEF"
1174 default:
1175 pattern = "PTR"
1176 chars = "0123456789abcdefABCDEF"
1177 }
1178 p := s[:i] + pattern
1179 for j := i; j < len(s); j++ {
1180 if !strings.ContainsRune(chars, rune(s[j])) {
1181 p += s[j:]
1182 break
1183 }
1184 }
1185 s = p
1186 }
1187 if s != tt.out {
1188 if _, ok := tt.val.(string); ok {
1189
1190
1191 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
1192 } else {
1193 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
1194 }
1195 }
1196 }
1197 }
1198
1199
1200
1201 func TestComplexFormatting(t *testing.T) {
1202 var yesNo = []bool{true, false}
1203 var values = []float64{1, 0, -1, posInf, negInf, NaN}
1204 for _, plus := range yesNo {
1205 for _, zero := range yesNo {
1206 for _, space := range yesNo {
1207 for _, char := range "fFeEgG" {
1208 realFmt := "%"
1209 if zero {
1210 realFmt += "0"
1211 }
1212 if space {
1213 realFmt += " "
1214 }
1215 if plus {
1216 realFmt += "+"
1217 }
1218 realFmt += "10.2"
1219 realFmt += string(char)
1220
1221 imagFmt := "%"
1222 if zero {
1223 imagFmt += "0"
1224 }
1225 imagFmt += "+"
1226 imagFmt += "10.2"
1227 imagFmt += string(char)
1228 for _, realValue := range values {
1229 for _, imagValue := range values {
1230 one := Sprintf(realFmt, complex(realValue, imagValue))
1231 two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
1232 if one != two {
1233 t.Error(f, one, two)
1234 }
1235 }
1236 }
1237 }
1238 }
1239 }
1240 }
1241 }
1242
1243 type SE []any
1244
1245 var reorderTests = []struct {
1246 fmt string
1247 val SE
1248 out string
1249 }{
1250 {"%[1]d", SE{1}, "1"},
1251 {"%[2]d", SE{2, 1}, "1"},
1252 {"%[2]d %[1]d", SE{1, 2}, "2 1"},
1253 {"%[2]*[1]d", SE{2, 5}, " 2"},
1254 {"%6.2f", SE{12.0}, " 12.00"},
1255 {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
1256 {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
1257 {"%10f", SE{12.0}, " 12.000000"},
1258 {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
1259 {"%.6f", SE{12.0}, "12.000000"},
1260 {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
1261 {"%6.f", SE{12.0}, " 12"},
1262 {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"},
1263
1264 {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
1265
1266
1267 {"%[d", SE{2, 1}, "%!d(BADINDEX)"},
1268 {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
1269 {"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
1270 {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
1271 {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
1272 {"%[3]", SE{2, 1}, "%!(NOVERB)"},
1273 {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
1274 {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
1275 {"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
1276 {"%.[2]d", SE{7}, "%!d(BADINDEX)"},
1277 {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
1278 {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
1279 {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"},
1280 {"%.[]", SE{}, "%!](BADINDEX)"},
1281 {"%.-3d", SE{42}, "%!-(int=42)3d"},
1282 {"%2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1283 {"%-2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1284 {"%.2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"},
1285 }
1286
1287 func TestReorder(t *testing.T) {
1288 for _, tt := range reorderTests {
1289 s := Sprintf(tt.fmt, tt.val...)
1290 if s != tt.out {
1291 t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
1292 }
1293 }
1294 }
1295
1296 func BenchmarkSprintfPadding(b *testing.B) {
1297 b.RunParallel(func(pb *testing.PB) {
1298 for pb.Next() {
1299 _ = Sprintf("%16f", 1.0)
1300 }
1301 })
1302 }
1303
1304 func BenchmarkSprintfEmpty(b *testing.B) {
1305 b.RunParallel(func(pb *testing.PB) {
1306 for pb.Next() {
1307 _ = Sprintf("")
1308 }
1309 })
1310 }
1311
1312 func BenchmarkSprintfString(b *testing.B) {
1313 b.RunParallel(func(pb *testing.PB) {
1314 for pb.Next() {
1315 _ = Sprintf("%s", "hello")
1316 }
1317 })
1318 }
1319
1320 func BenchmarkSprintfTruncateString(b *testing.B) {
1321 b.RunParallel(func(pb *testing.PB) {
1322 for pb.Next() {
1323 _ = Sprintf("%.3s", "日本語日本語日本語日本語")
1324 }
1325 })
1326 }
1327
1328 func BenchmarkSprintfTruncateBytes(b *testing.B) {
1329 var bytes any = []byte("日本語日本語日本語日本語")
1330 b.RunParallel(func(pb *testing.PB) {
1331 for pb.Next() {
1332 _ = Sprintf("%.3s", bytes)
1333 }
1334 })
1335 }
1336
1337 func BenchmarkSprintfSlowParsingPath(b *testing.B) {
1338 b.RunParallel(func(pb *testing.PB) {
1339 for pb.Next() {
1340 _ = Sprintf("%.v", nil)
1341 }
1342 })
1343 }
1344
1345 func BenchmarkSprintfQuoteString(b *testing.B) {
1346 b.RunParallel(func(pb *testing.PB) {
1347 for pb.Next() {
1348 _ = Sprintf("%q", "日本語日本語日本語")
1349 }
1350 })
1351 }
1352
1353 func BenchmarkSprintfInt(b *testing.B) {
1354 b.RunParallel(func(pb *testing.PB) {
1355 for pb.Next() {
1356 _ = Sprintf("%d", 5)
1357 }
1358 })
1359 }
1360
1361 func BenchmarkSprintfIntInt(b *testing.B) {
1362 b.RunParallel(func(pb *testing.PB) {
1363 for pb.Next() {
1364 _ = Sprintf("%d %d", 5, 6)
1365 }
1366 })
1367 }
1368
1369 func BenchmarkSprintfPrefixedInt(b *testing.B) {
1370 b.RunParallel(func(pb *testing.PB) {
1371 for pb.Next() {
1372 _ = Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
1373 }
1374 })
1375 }
1376
1377 func BenchmarkSprintfFloat(b *testing.B) {
1378 b.RunParallel(func(pb *testing.PB) {
1379 for pb.Next() {
1380 _ = Sprintf("%g", 5.23184)
1381 }
1382 })
1383 }
1384
1385 func BenchmarkSprintfComplex(b *testing.B) {
1386 b.RunParallel(func(pb *testing.PB) {
1387 for pb.Next() {
1388 _ = Sprintf("%f", 5.23184+5.23184i)
1389 }
1390 })
1391 }
1392
1393 func BenchmarkSprintfBoolean(b *testing.B) {
1394 b.RunParallel(func(pb *testing.PB) {
1395 for pb.Next() {
1396 _ = Sprintf("%t", true)
1397 }
1398 })
1399 }
1400
1401 func BenchmarkSprintfHexString(b *testing.B) {
1402 b.RunParallel(func(pb *testing.PB) {
1403 for pb.Next() {
1404 _ = Sprintf("% #x", "0123456789abcdef")
1405 }
1406 })
1407 }
1408
1409 func BenchmarkSprintfHexBytes(b *testing.B) {
1410 data := []byte("0123456789abcdef")
1411 b.RunParallel(func(pb *testing.PB) {
1412 for pb.Next() {
1413 _ = Sprintf("% #x", data)
1414 }
1415 })
1416 }
1417
1418 func BenchmarkSprintfBytes(b *testing.B) {
1419 data := []byte("0123456789abcdef")
1420 b.RunParallel(func(pb *testing.PB) {
1421 for pb.Next() {
1422 _ = Sprintf("%v", data)
1423 }
1424 })
1425 }
1426
1427 func BenchmarkSprintfStringer(b *testing.B) {
1428 stringer := I(12345)
1429 b.RunParallel(func(pb *testing.PB) {
1430 for pb.Next() {
1431 _ = Sprintf("%v", stringer)
1432 }
1433 })
1434 }
1435
1436 func BenchmarkSprintfStructure(b *testing.B) {
1437 s := &[]any{SI{12345}, map[int]string{0: "hello"}}
1438 b.RunParallel(func(pb *testing.PB) {
1439 for pb.Next() {
1440 _ = Sprintf("%#v", s)
1441 }
1442 })
1443 }
1444
1445 func BenchmarkManyArgs(b *testing.B) {
1446 b.RunParallel(func(pb *testing.PB) {
1447 var buf bytes.Buffer
1448 for pb.Next() {
1449 buf.Reset()
1450 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
1451 }
1452 })
1453 }
1454
1455 func BenchmarkFprintInt(b *testing.B) {
1456 var buf bytes.Buffer
1457 for i := 0; i < b.N; i++ {
1458 buf.Reset()
1459 Fprint(&buf, 123456)
1460 }
1461 }
1462
1463 func BenchmarkFprintfBytes(b *testing.B) {
1464 data := []byte(string("0123456789"))
1465 var buf bytes.Buffer
1466 for i := 0; i < b.N; i++ {
1467 buf.Reset()
1468 Fprintf(&buf, "%s", data)
1469 }
1470 }
1471
1472 func BenchmarkFprintIntNoAlloc(b *testing.B) {
1473 var x any = 123456
1474 var buf bytes.Buffer
1475 for i := 0; i < b.N; i++ {
1476 buf.Reset()
1477 Fprint(&buf, x)
1478 }
1479 }
1480
1481 var mallocBuf bytes.Buffer
1482 var mallocPointer *int
1483
1484 var mallocTest = []struct {
1485 count int
1486 desc string
1487 fn func()
1488 }{
1489 {0, `Sprintf("")`, func() { _ = Sprintf("") }},
1490 {1, `Sprintf("xxx")`, func() { _ = Sprintf("xxx") }},
1491 {0, `Sprintf("%x")`, func() { _ = Sprintf("%x", 7) }},
1492 {1, `Sprintf("%x")`, func() { _ = Sprintf("%x", 1<<16) }},
1493 {3, `Sprintf("%80000s")`, func() { _ = Sprintf("%80000s", "hello") }},
1494 {1, `Sprintf("%s")`, func() { _ = Sprintf("%s", "hello") }},
1495 {1, `Sprintf("%x %x")`, func() { _ = Sprintf("%x %x", 7, 112) }},
1496 {1, `Sprintf("%g")`, func() { _ = Sprintf("%g", float32(3.14159)) }},
1497 {0, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
1498 {0, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); s := "hello"; Fprintf(&mallocBuf, "%s", s) }},
1499 {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); s := "hello"; Fprintf(&mallocBuf, "%s", noliteral(s)) }},
1500 {0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 7) }},
1501 {0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 1<<16) }},
1502 {0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); i := 1 << 16; Fprintf(&mallocBuf, "%x", i) }},
1503 {1, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); i := 1 << 16; Fprintf(&mallocBuf, "%x", noliteral(i)) }},
1504 {4, `Fprintf(buf, "%v")`, func() { mallocBuf.Reset(); s := []int{1, 2}; Fprintf(&mallocBuf, "%v", s) }},
1505 {0, `Fprintf(buf, "%v")`, func() { mallocBuf.Reset(); type P struct{ x, y int }; Fprintf(&mallocBuf, "%v", P{1, 2}) }},
1506 {1, `Fprintf(buf, "%v")`, func() { mallocBuf.Reset(); type P struct{ x, y int }; Fprintf(&mallocBuf, "%v", noliteral(P{1, 2})) }},
1507 {2, `Fprintf(buf, "%80000s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%80000s", "hello") }},
1508
1509 {0, `Fprintf(buf, "%x %x %x")`, func() {
1510 mallocBuf.Reset()
1511 Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer)
1512 }},
1513 }
1514
1515 var _ bytes.Buffer
1516
1517 func TestCountMallocs(t *testing.T) {
1518 switch {
1519 case testing.Short():
1520 t.Skip("skipping malloc count in short mode")
1521 case race.Enabled:
1522 t.Skip("skipping malloc count under race detector")
1523 }
1524 for _, mt := range mallocTest {
1525 mallocs := testing.AllocsPerRun(100, mt.fn)
1526 if got, max := mallocs, float64(mt.count); got != max {
1527 t.Errorf("%s: got %v allocs, want %v", mt.desc, got, max)
1528 }
1529 }
1530 }
1531
1532 type flagPrinter struct{}
1533
1534 func (flagPrinter) Format(f State, c rune) {
1535 s := "%"
1536 for i := 0; i < 128; i++ {
1537 if f.Flag(i) {
1538 s += string(rune(i))
1539 }
1540 }
1541 if w, ok := f.Width(); ok {
1542 s += Sprintf("%d", w)
1543 }
1544 if p, ok := f.Precision(); ok {
1545 s += Sprintf(".%d", p)
1546 }
1547 s += string(c)
1548 io.WriteString(f, "["+s+"]")
1549 }
1550
1551 var flagtests = []struct {
1552 in string
1553 out string
1554 }{
1555 {"%a", "[%a]"},
1556 {"%-a", "[%-a]"},
1557 {"%+a", "[%+a]"},
1558 {"%#a", "[%#a]"},
1559 {"% a", "[% a]"},
1560 {"%0a", "[%0a]"},
1561 {"%1.2a", "[%1.2a]"},
1562 {"%-1.2a", "[%-1.2a]"},
1563 {"%+1.2a", "[%+1.2a]"},
1564 {"%-+1.2a", "[%+-1.2a]"},
1565 {"%-+1.2abc", "[%+-1.2a]bc"},
1566 {"%-1.2abc", "[%-1.2a]bc"},
1567 {"%-0abc", "[%-0a]bc"},
1568 }
1569
1570 func TestFlagParser(t *testing.T) {
1571 var flagprinter flagPrinter
1572 for _, tt := range flagtests {
1573 s := Sprintf(tt.in, &flagprinter)
1574 if s != tt.out {
1575 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
1576 }
1577 }
1578 }
1579
1580 func TestStructPrinter(t *testing.T) {
1581 type T struct {
1582 a string
1583 b string
1584 c int
1585 }
1586 var s T
1587 s.a = "abc"
1588 s.b = "def"
1589 s.c = 123
1590 var tests = []struct {
1591 fmt string
1592 out string
1593 }{
1594 {"%v", "{abc def 123}"},
1595 {"%+v", "{a:abc b:def c:123}"},
1596 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`},
1597 }
1598 for _, tt := range tests {
1599 out := Sprintf(tt.fmt, s)
1600 if out != tt.out {
1601 t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
1602 }
1603
1604 out = Sprintf(tt.fmt, &s)
1605 if out != "&"+tt.out {
1606 t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
1607 }
1608 }
1609 }
1610
1611 func TestSlicePrinter(t *testing.T) {
1612 slice := []int{}
1613 s := Sprint(slice)
1614 if s != "[]" {
1615 t.Errorf("empty slice printed as %q not %q", s, "[]")
1616 }
1617 slice = []int{1, 2, 3}
1618 s = Sprint(slice)
1619 if s != "[1 2 3]" {
1620 t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
1621 }
1622 s = Sprint(&slice)
1623 if s != "&[1 2 3]" {
1624 t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
1625 }
1626 }
1627
1628
1629
1630 func presentInMap(s string, a []string, t *testing.T) {
1631 for i := 0; i < len(a); i++ {
1632 loc := strings.Index(s, a[i])
1633 if loc < 0 {
1634 t.Errorf("map print: expected to find %q in %q", a[i], s)
1635 }
1636
1637 loc += len(a[i])
1638 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
1639 t.Errorf("map print: %q not properly terminated in %q", a[i], s)
1640 }
1641 }
1642 }
1643
1644 func TestMapPrinter(t *testing.T) {
1645 m0 := make(map[int]string)
1646 s := Sprint(m0)
1647 if s != "map[]" {
1648 t.Errorf("empty map printed as %q not %q", s, "map[]")
1649 }
1650 m1 := map[int]string{1: "one", 2: "two", 3: "three"}
1651 a := []string{"1:one", "2:two", "3:three"}
1652 presentInMap(Sprintf("%v", m1), a, t)
1653 presentInMap(Sprint(m1), a, t)
1654
1655 if !strings.HasPrefix(Sprint(&m1), "&") {
1656 t.Errorf("no initial & for address of map")
1657 }
1658 presentInMap(Sprintf("%v", &m1), a, t)
1659 presentInMap(Sprint(&m1), a, t)
1660 }
1661
1662 func TestEmptyMap(t *testing.T) {
1663 const emptyMapStr = "map[]"
1664 var m map[string]int
1665 s := Sprint(m)
1666 if s != emptyMapStr {
1667 t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
1668 }
1669 m = make(map[string]int)
1670 s = Sprint(m)
1671 if s != emptyMapStr {
1672 t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
1673 }
1674 }
1675
1676
1677
1678 func TestBlank(t *testing.T) {
1679 got := Sprint("<", 1, ">:", 1, 2, 3, "!")
1680 expect := "<1>:1 2 3!"
1681 if got != expect {
1682 t.Errorf("got %q expected %q", got, expect)
1683 }
1684 }
1685
1686
1687
1688 func TestBlankln(t *testing.T) {
1689 got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
1690 expect := "< 1 >: 1 2 3 !\n"
1691 if got != expect {
1692 t.Errorf("got %q expected %q", got, expect)
1693 }
1694 }
1695
1696
1697 func TestFormatterPrintln(t *testing.T) {
1698 f := F(1)
1699 expect := "<v=F(1)>\n"
1700 s := Sprint(f, "\n")
1701 if s != expect {
1702 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
1703 }
1704 s = Sprintln(f)
1705 if s != expect {
1706 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
1707 }
1708 s = Sprintf("%v\n", f)
1709 if s != expect {
1710 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
1711 }
1712 }
1713
1714 func args(a ...any) []any { return a }
1715
1716 var startests = []struct {
1717 fmt string
1718 in []any
1719 out string
1720 }{
1721 {"%*d", args(4, 42), " 42"},
1722 {"%-*d", args(4, 42), "42 "},
1723 {"%*d", args(-4, 42), "42 "},
1724 {"%-*d", args(-4, 42), "42 "},
1725 {"%.*d", args(4, 42), "0042"},
1726 {"%*.*d", args(8, 4, 42), " 0042"},
1727 {"%0*d", args(4, 42), "0042"},
1728
1729 {"%0*d", args(uint(4), 42), "0042"},
1730 {"%0*d", args(uint64(4), 42), "0042"},
1731 {"%0*d", args('\x04', 42), "0042"},
1732 {"%0*d", args(uintptr(4), 42), "0042"},
1733
1734
1735 {"%*d", args(nil, 42), "%!(BADWIDTH)42"},
1736 {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"},
1737 {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"},
1738 {"%.*d", args(nil, 42), "%!(BADPREC)42"},
1739 {"%.*d", args(-1, 42), "%!(BADPREC)42"},
1740 {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"},
1741 {"%.*d", args(uint(1e7), 42), "%!(BADPREC)42"},
1742 {"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"},
1743 {"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"},
1744 {"%*d", args(5, "foo"), "%!d(string= foo)"},
1745 {"%*% %d", args(20, 5), "% 5"},
1746 {"%*", args(4), "%!(NOVERB)"},
1747 }
1748
1749 func TestWidthAndPrecision(t *testing.T) {
1750 for i, tt := range startests {
1751 s := Sprintf(tt.fmt, tt.in...)
1752 if s != tt.out {
1753 t.Errorf("#%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
1754 }
1755 }
1756 }
1757
1758
1759 type PanicS struct {
1760 message any
1761 }
1762
1763
1764 func (p PanicS) String() string {
1765 panic(p.message)
1766 }
1767
1768
1769 type PanicGo struct {
1770 message any
1771 }
1772
1773
1774 func (p PanicGo) GoString() string {
1775 panic(p.message)
1776 }
1777
1778
1779 type PanicF struct {
1780 message any
1781 }
1782
1783
1784 func (p PanicF) Format(f State, c rune) {
1785 panic(p.message)
1786 }
1787
1788 var panictests = []struct {
1789 fmt string
1790 in any
1791 out string
1792 }{
1793
1794 {"%s", (*PanicS)(nil), "<nil>"},
1795 {"%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=String method: unexpected EOF)"},
1796 {"%s", PanicS{3}, "%!s(PANIC=String method: 3)"},
1797
1798 {"%#v", (*PanicGo)(nil), "<nil>"},
1799 {"%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=GoString method: unexpected EOF)"},
1800 {"%#v", PanicGo{3}, "%!v(PANIC=GoString method: 3)"},
1801
1802 {"%#v", []any{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=GoString method: 3), %!v(PANIC=GoString method: 3)}"},
1803
1804 {"%s", (*PanicF)(nil), "<nil>"},
1805 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=Format method: unexpected EOF)"},
1806 {"%s", PanicF{3}, "%!s(PANIC=Format method: 3)"},
1807 }
1808
1809 func TestPanics(t *testing.T) {
1810 for i, tt := range panictests {
1811 s := Sprintf(tt.fmt, tt.in)
1812 if s != tt.out {
1813 t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
1814 }
1815 }
1816 }
1817
1818
1819 var recurCount = 0
1820
1821 type Recur struct {
1822 i int
1823 failed *bool
1824 }
1825
1826 func (r *Recur) String() string {
1827 if recurCount++; recurCount > 10 {
1828 *r.failed = true
1829 return "FAIL"
1830 }
1831
1832
1833
1834 return Sprintf("recur@%p value: %d", r, r.i)
1835 }
1836
1837 func TestBadVerbRecursion(t *testing.T) {
1838 failed := false
1839 r := &Recur{3, &failed}
1840 _ = Sprintf("recur@%p value: %d\n", &r, r.i)
1841 if failed {
1842 t.Error("fail with pointer")
1843 }
1844 failed = false
1845 r = &Recur{4, &failed}
1846 _ = Sprintf("recur@%p, value: %d\n", r, r.i)
1847 if failed {
1848 t.Error("fail with value")
1849 }
1850 }
1851
1852 func TestIsSpace(t *testing.T) {
1853
1854
1855 for i := rune(0); i <= unicode.MaxRune; i++ {
1856 if IsSpace(i) != unicode.IsSpace(i) {
1857 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
1858 }
1859 }
1860 }
1861
1862 func hideFromVet(s string) string { return s }
1863
1864 func TestNilDoesNotBecomeTyped(t *testing.T) {
1865 type A struct{}
1866 type B struct{}
1867 var a *A = nil
1868 var b B = B{}
1869 got := Sprintf(hideFromVet("%s %s %s %s %s"), nil, a, nil, b, nil)
1870 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
1871 if got != expect {
1872 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
1873 }
1874 }
1875
1876 var formatterFlagTests = []struct {
1877 in string
1878 val any
1879 out string
1880 }{
1881
1882 {"%a", flagPrinter{}, "[%a]"},
1883 {"%-a", flagPrinter{}, "[%-a]"},
1884 {"%+a", flagPrinter{}, "[%+a]"},
1885 {"%#a", flagPrinter{}, "[%#a]"},
1886 {"% a", flagPrinter{}, "[% a]"},
1887 {"%0a", flagPrinter{}, "[%0a]"},
1888 {"%1.2a", flagPrinter{}, "[%1.2a]"},
1889 {"%-1.2a", flagPrinter{}, "[%-1.2a]"},
1890 {"%+1.2a", flagPrinter{}, "[%+1.2a]"},
1891 {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
1892 {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
1893 {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
1894 {"%-0abc", flagPrinter{}, "[%-0a]bc"},
1895
1896
1897 {"%a", [1]flagPrinter{}, "[[%a]]"},
1898 {"%-a", [1]flagPrinter{}, "[[%-a]]"},
1899 {"%+a", [1]flagPrinter{}, "[[%+a]]"},
1900 {"%#a", [1]flagPrinter{}, "[[%#a]]"},
1901 {"% a", [1]flagPrinter{}, "[[% a]]"},
1902 {"%0a", [1]flagPrinter{}, "[[%0a]]"},
1903 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
1904 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
1905 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
1906 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
1907 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
1908 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
1909 {"%-0abc", [1]flagPrinter{}, "[[%-0a]]bc"},
1910
1911
1912 {"%v", flagPrinter{}, "[%v]"},
1913 {"%-v", flagPrinter{}, "[%-v]"},
1914 {"%+v", flagPrinter{}, "[%+v]"},
1915 {"%#v", flagPrinter{}, "[%#v]"},
1916 {"% v", flagPrinter{}, "[% v]"},
1917 {"%0v", flagPrinter{}, "[%0v]"},
1918 {"%1.2v", flagPrinter{}, "[%1.2v]"},
1919 {"%-1.2v", flagPrinter{}, "[%-1.2v]"},
1920 {"%+1.2v", flagPrinter{}, "[%+1.2v]"},
1921 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
1922 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
1923 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
1924 {"%-0vbc", flagPrinter{}, "[%-0v]bc"},
1925
1926
1927 {"%v", [1]flagPrinter{}, "[[%v]]"},
1928 {"%-v", [1]flagPrinter{}, "[[%-v]]"},
1929 {"%+v", [1]flagPrinter{}, "[[%+v]]"},
1930 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"},
1931 {"% v", [1]flagPrinter{}, "[[% v]]"},
1932 {"%0v", [1]flagPrinter{}, "[[%0v]]"},
1933 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
1934 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
1935 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
1936 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
1937 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
1938 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
1939 {"%-0vbc", [1]flagPrinter{}, "[[%-0v]]bc"},
1940 }
1941
1942 func TestFormatterFlags(t *testing.T) {
1943 for _, tt := range formatterFlagTests {
1944 s := Sprintf(tt.in, tt.val)
1945 if s != tt.out {
1946 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out)
1947 }
1948 }
1949 }
1950
1951 func TestParsenum(t *testing.T) {
1952 testCases := []struct {
1953 s string
1954 start, end int
1955 num int
1956 isnum bool
1957 newi int
1958 }{
1959 {"a123", 0, 4, 0, false, 0},
1960 {"1234", 1, 1, 0, false, 1},
1961 {"123a", 0, 4, 123, true, 3},
1962 {"12a3", 0, 4, 12, true, 2},
1963 {"1234", 0, 4, 1234, true, 4},
1964 {"1a234", 1, 3, 0, false, 1},
1965 }
1966 for _, tt := range testCases {
1967 num, isnum, newi := Parsenum(tt.s, tt.start, tt.end)
1968 if num != tt.num || isnum != tt.isnum || newi != tt.newi {
1969 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)
1970 }
1971 }
1972 }
1973
1974
1975
1976
1977 const (
1978 appendResult = "hello world, 23"
1979 hello = "hello "
1980 )
1981
1982 func TestAppendf(t *testing.T) {
1983 b := make([]byte, 100)
1984 b = b[:copy(b, hello)]
1985 got := Appendf(b, "world, %d", 23)
1986 if string(got) != appendResult {
1987 t.Fatalf("Appendf returns %q not %q", got, appendResult)
1988 }
1989 if &b[0] != &got[0] {
1990 t.Fatalf("Appendf allocated a new slice")
1991 }
1992 }
1993
1994 func TestAppend(t *testing.T) {
1995 b := make([]byte, 100)
1996 b = b[:copy(b, hello)]
1997 got := Append(b, "world", ", ", 23)
1998 if string(got) != appendResult {
1999 t.Fatalf("Append returns %q not %q", got, appendResult)
2000 }
2001 if &b[0] != &got[0] {
2002 t.Fatalf("Append allocated a new slice")
2003 }
2004 }
2005
2006 func TestAppendln(t *testing.T) {
2007 b := make([]byte, 100)
2008 b = b[:copy(b, hello)]
2009 got := Appendln(b, "world,", 23)
2010 if string(got) != appendResult+"\n" {
2011 t.Fatalf("Appendln returns %q not %q", got, appendResult+"\n")
2012 }
2013 if &b[0] != &got[0] {
2014 t.Fatalf("Appendln allocated a new slice")
2015 }
2016 }
2017
2018
2019
2020
2021 func noliteral[T any](t T) T {
2022 return t
2023 }
2024
View as plain text