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