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