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