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