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