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