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