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 {"%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 }
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 {0, `Sprintf("%x")`, func() { _ = Sprintf("%x", 7) }},
1433 {1, `Sprintf("%x")`, func() { _ = Sprintf("%x", 1<<16) }},
1434 {3, `Sprintf("%80000s")`, func() { _ = Sprintf("%80000s", "hello") }},
1435 {1, `Sprintf("%s")`, func() { _ = Sprintf("%s", "hello") }},
1436 {1, `Sprintf("%x %x")`, func() { _ = Sprintf("%x %x", 7, 112) }},
1437 {1, `Sprintf("%g")`, func() { _ = Sprintf("%g", float32(3.14159)) }},
1438 {0, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
1439 {0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 7) }},
1440 {0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 1<<16) }},
1441 {2, `Fprintf(buf, "%80000s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%80000s", "hello") }},
1442
1443 {0, `Fprintf(buf, "%x %x %x")`, func() {
1444 mallocBuf.Reset()
1445 Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer)
1446 }},
1447 }
1448
1449 var _ bytes.Buffer
1450
1451 func TestCountMallocs(t *testing.T) {
1452 switch {
1453 case testing.Short():
1454 t.Skip("skipping malloc count in short mode")
1455 case runtime.GOMAXPROCS(0) > 1:
1456 t.Skip("skipping; GOMAXPROCS>1")
1457 case race.Enabled:
1458 t.Skip("skipping malloc count under race detector")
1459 }
1460 for _, mt := range mallocTest {
1461 mallocs := testing.AllocsPerRun(100, mt.fn)
1462 if got, max := mallocs, float64(mt.count); got > max {
1463 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
1464 }
1465 }
1466 }
1467
1468 type flagPrinter struct{}
1469
1470 func (flagPrinter) Format(f State, c rune) {
1471 s := "%"
1472 for i := 0; i < 128; i++ {
1473 if f.Flag(i) {
1474 s += string(rune(i))
1475 }
1476 }
1477 if w, ok := f.Width(); ok {
1478 s += Sprintf("%d", w)
1479 }
1480 if p, ok := f.Precision(); ok {
1481 s += Sprintf(".%d", p)
1482 }
1483 s += string(c)
1484 io.WriteString(f, "["+s+"]")
1485 }
1486
1487 var flagtests = []struct {
1488 in string
1489 out string
1490 }{
1491 {"%a", "[%a]"},
1492 {"%-a", "[%-a]"},
1493 {"%+a", "[%+a]"},
1494 {"%#a", "[%#a]"},
1495 {"% a", "[% a]"},
1496 {"%0a", "[%0a]"},
1497 {"%1.2a", "[%1.2a]"},
1498 {"%-1.2a", "[%-1.2a]"},
1499 {"%+1.2a", "[%+1.2a]"},
1500 {"%-+1.2a", "[%+-1.2a]"},
1501 {"%-+1.2abc", "[%+-1.2a]bc"},
1502 {"%-1.2abc", "[%-1.2a]bc"},
1503 {"%-0abc", "[%-0a]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 {"%-0abc", flagPrinter{}, "[%-0a]bc"},
1831
1832
1833 {"%a", [1]flagPrinter{}, "[[%a]]"},
1834 {"%-a", [1]flagPrinter{}, "[[%-a]]"},
1835 {"%+a", [1]flagPrinter{}, "[[%+a]]"},
1836 {"%#a", [1]flagPrinter{}, "[[%#a]]"},
1837 {"% a", [1]flagPrinter{}, "[[% a]]"},
1838 {"%0a", [1]flagPrinter{}, "[[%0a]]"},
1839 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
1840 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
1841 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
1842 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
1843 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
1844 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
1845 {"%-0abc", [1]flagPrinter{}, "[[%-0a]]bc"},
1846
1847
1848 {"%v", flagPrinter{}, "[%v]"},
1849 {"%-v", flagPrinter{}, "[%-v]"},
1850 {"%+v", flagPrinter{}, "[%+v]"},
1851 {"%#v", flagPrinter{}, "[%#v]"},
1852 {"% v", flagPrinter{}, "[% v]"},
1853 {"%0v", flagPrinter{}, "[%0v]"},
1854 {"%1.2v", flagPrinter{}, "[%1.2v]"},
1855 {"%-1.2v", flagPrinter{}, "[%-1.2v]"},
1856 {"%+1.2v", flagPrinter{}, "[%+1.2v]"},
1857 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
1858 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
1859 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
1860 {"%-0vbc", flagPrinter{}, "[%-0v]bc"},
1861
1862
1863 {"%v", [1]flagPrinter{}, "[[%v]]"},
1864 {"%-v", [1]flagPrinter{}, "[[%-v]]"},
1865 {"%+v", [1]flagPrinter{}, "[[%+v]]"},
1866 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"},
1867 {"% v", [1]flagPrinter{}, "[[% v]]"},
1868 {"%0v", [1]flagPrinter{}, "[[%0v]]"},
1869 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
1870 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
1871 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
1872 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
1873 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
1874 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
1875 {"%-0vbc", [1]flagPrinter{}, "[[%-0v]]bc"},
1876 }
1877
1878 func TestFormatterFlags(t *testing.T) {
1879 for _, tt := range formatterFlagTests {
1880 s := Sprintf(tt.in, tt.val)
1881 if s != tt.out {
1882 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out)
1883 }
1884 }
1885 }
1886
1887 func TestParsenum(t *testing.T) {
1888 testCases := []struct {
1889 s string
1890 start, end int
1891 num int
1892 isnum bool
1893 newi int
1894 }{
1895 {"a123", 0, 4, 0, false, 0},
1896 {"1234", 1, 1, 0, false, 1},
1897 {"123a", 0, 4, 123, true, 3},
1898 {"12a3", 0, 4, 12, true, 2},
1899 {"1234", 0, 4, 1234, true, 4},
1900 {"1a234", 1, 3, 0, false, 1},
1901 }
1902 for _, tt := range testCases {
1903 num, isnum, newi := Parsenum(tt.s, tt.start, tt.end)
1904 if num != tt.num || isnum != tt.isnum || newi != tt.newi {
1905 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)
1906 }
1907 }
1908 }
1909
1910
1911
1912
1913 const (
1914 appendResult = "hello world, 23"
1915 hello = "hello "
1916 )
1917
1918 func TestAppendf(t *testing.T) {
1919 b := make([]byte, 100)
1920 b = b[:copy(b, hello)]
1921 got := Appendf(b, "world, %d", 23)
1922 if string(got) != appendResult {
1923 t.Fatalf("Appendf returns %q not %q", got, appendResult)
1924 }
1925 if &b[0] != &got[0] {
1926 t.Fatalf("Appendf allocated a new slice")
1927 }
1928 }
1929
1930 func TestAppend(t *testing.T) {
1931 b := make([]byte, 100)
1932 b = b[:copy(b, hello)]
1933 got := Append(b, "world", ", ", 23)
1934 if string(got) != appendResult {
1935 t.Fatalf("Append returns %q not %q", got, appendResult)
1936 }
1937 if &b[0] != &got[0] {
1938 t.Fatalf("Append allocated a new slice")
1939 }
1940 }
1941
1942 func TestAppendln(t *testing.T) {
1943 b := make([]byte, 100)
1944 b = b[:copy(b, hello)]
1945 got := Appendln(b, "world,", 23)
1946 if string(got) != appendResult+"\n" {
1947 t.Fatalf("Appendln returns %q not %q", got, appendResult+"\n")
1948 }
1949 if &b[0] != &got[0] {
1950 t.Fatalf("Appendln allocated a new slice")
1951 }
1952 }
1953
View as plain text