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