github.com/filosottile/go@v0.0.0-20170906193555-dbed9972d994/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 BenchmarkSprintfSlowParsingPath(b *testing.B) { 1205 b.RunParallel(func(pb *testing.PB) { 1206 for pb.Next() { 1207 Sprintf("%.v", nil) 1208 } 1209 }) 1210 } 1211 1212 func BenchmarkSprintfQuoteString(b *testing.B) { 1213 b.RunParallel(func(pb *testing.PB) { 1214 for pb.Next() { 1215 Sprintf("%q", "日本語日本語日本語") 1216 } 1217 }) 1218 } 1219 1220 func BenchmarkSprintfInt(b *testing.B) { 1221 b.RunParallel(func(pb *testing.PB) { 1222 for pb.Next() { 1223 Sprintf("%d", 5) 1224 } 1225 }) 1226 } 1227 1228 func BenchmarkSprintfIntInt(b *testing.B) { 1229 b.RunParallel(func(pb *testing.PB) { 1230 for pb.Next() { 1231 Sprintf("%d %d", 5, 6) 1232 } 1233 }) 1234 } 1235 1236 func BenchmarkSprintfPrefixedInt(b *testing.B) { 1237 b.RunParallel(func(pb *testing.PB) { 1238 for pb.Next() { 1239 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6) 1240 } 1241 }) 1242 } 1243 1244 func BenchmarkSprintfFloat(b *testing.B) { 1245 b.RunParallel(func(pb *testing.PB) { 1246 for pb.Next() { 1247 Sprintf("%g", 5.23184) 1248 } 1249 }) 1250 } 1251 1252 func BenchmarkSprintfComplex(b *testing.B) { 1253 b.RunParallel(func(pb *testing.PB) { 1254 for pb.Next() { 1255 Sprintf("%f", 5.23184+5.23184i) 1256 } 1257 }) 1258 } 1259 1260 func BenchmarkSprintfBoolean(b *testing.B) { 1261 b.RunParallel(func(pb *testing.PB) { 1262 for pb.Next() { 1263 Sprintf("%t", true) 1264 } 1265 }) 1266 } 1267 1268 func BenchmarkSprintfHexString(b *testing.B) { 1269 b.RunParallel(func(pb *testing.PB) { 1270 for pb.Next() { 1271 Sprintf("% #x", "0123456789abcdef") 1272 } 1273 }) 1274 } 1275 1276 func BenchmarkSprintfHexBytes(b *testing.B) { 1277 data := []byte("0123456789abcdef") 1278 b.RunParallel(func(pb *testing.PB) { 1279 for pb.Next() { 1280 Sprintf("% #x", data) 1281 } 1282 }) 1283 } 1284 1285 func BenchmarkSprintfBytes(b *testing.B) { 1286 data := []byte("0123456789abcdef") 1287 b.RunParallel(func(pb *testing.PB) { 1288 for pb.Next() { 1289 Sprintf("%v", data) 1290 } 1291 }) 1292 } 1293 1294 func BenchmarkSprintfStringer(b *testing.B) { 1295 stringer := I(12345) 1296 b.RunParallel(func(pb *testing.PB) { 1297 for pb.Next() { 1298 Sprintf("%v", stringer) 1299 } 1300 }) 1301 } 1302 1303 func BenchmarkSprintfStructure(b *testing.B) { 1304 s := &[]interface{}{SI{12345}, map[int]string{0: "hello"}} 1305 b.RunParallel(func(pb *testing.PB) { 1306 for pb.Next() { 1307 Sprintf("%#v", s) 1308 } 1309 }) 1310 } 1311 1312 func BenchmarkManyArgs(b *testing.B) { 1313 b.RunParallel(func(pb *testing.PB) { 1314 var buf bytes.Buffer 1315 for pb.Next() { 1316 buf.Reset() 1317 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world") 1318 } 1319 }) 1320 } 1321 1322 func BenchmarkFprintInt(b *testing.B) { 1323 var buf bytes.Buffer 1324 for i := 0; i < b.N; i++ { 1325 buf.Reset() 1326 Fprint(&buf, 123456) 1327 } 1328 } 1329 1330 func BenchmarkFprintfBytes(b *testing.B) { 1331 data := []byte(string("0123456789")) 1332 var buf bytes.Buffer 1333 for i := 0; i < b.N; i++ { 1334 buf.Reset() 1335 Fprintf(&buf, "%s", data) 1336 } 1337 } 1338 1339 func BenchmarkFprintIntNoAlloc(b *testing.B) { 1340 var x interface{} = 123456 1341 var buf bytes.Buffer 1342 for i := 0; i < b.N; i++ { 1343 buf.Reset() 1344 Fprint(&buf, x) 1345 } 1346 } 1347 1348 var mallocBuf bytes.Buffer 1349 var mallocPointer *int // A pointer so we know the interface value won't allocate. 1350 1351 var mallocTest = []struct { 1352 count int 1353 desc string 1354 fn func() 1355 }{ 1356 {0, `Sprintf("")`, func() { Sprintf("") }}, 1357 {1, `Sprintf("xxx")`, func() { Sprintf("xxx") }}, 1358 {2, `Sprintf("%x")`, func() { Sprintf("%x", 7) }}, 1359 {2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }}, 1360 {3, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }}, 1361 {2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1? 1362 {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }}, 1363 // If the interface value doesn't need to allocate, amortized allocation overhead should be zero. 1364 {0, `Fprintf(buf, "%x %x %x")`, func() { 1365 mallocBuf.Reset() 1366 Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer) 1367 }}, 1368 } 1369 1370 var _ bytes.Buffer 1371 1372 func TestCountMallocs(t *testing.T) { 1373 switch { 1374 case testing.Short(): 1375 t.Skip("skipping malloc count in short mode") 1376 case runtime.GOMAXPROCS(0) > 1: 1377 t.Skip("skipping; GOMAXPROCS>1") 1378 case race.Enabled: 1379 t.Skip("skipping malloc count under race detector") 1380 } 1381 for _, mt := range mallocTest { 1382 mallocs := testing.AllocsPerRun(100, mt.fn) 1383 if got, max := mallocs, float64(mt.count); got > max { 1384 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max) 1385 } 1386 } 1387 } 1388 1389 type flagPrinter struct{} 1390 1391 func (flagPrinter) Format(f State, c rune) { 1392 s := "%" 1393 for i := 0; i < 128; i++ { 1394 if f.Flag(i) { 1395 s += string(i) 1396 } 1397 } 1398 if w, ok := f.Width(); ok { 1399 s += Sprintf("%d", w) 1400 } 1401 if p, ok := f.Precision(); ok { 1402 s += Sprintf(".%d", p) 1403 } 1404 s += string(c) 1405 io.WriteString(f, "["+s+"]") 1406 } 1407 1408 var flagtests = []struct { 1409 in string 1410 out string 1411 }{ 1412 {"%a", "[%a]"}, 1413 {"%-a", "[%-a]"}, 1414 {"%+a", "[%+a]"}, 1415 {"%#a", "[%#a]"}, 1416 {"% a", "[% a]"}, 1417 {"%0a", "[%0a]"}, 1418 {"%1.2a", "[%1.2a]"}, 1419 {"%-1.2a", "[%-1.2a]"}, 1420 {"%+1.2a", "[%+1.2a]"}, 1421 {"%-+1.2a", "[%+-1.2a]"}, 1422 {"%-+1.2abc", "[%+-1.2a]bc"}, 1423 {"%-1.2abc", "[%-1.2a]bc"}, 1424 } 1425 1426 func TestFlagParser(t *testing.T) { 1427 var flagprinter flagPrinter 1428 for _, tt := range flagtests { 1429 s := Sprintf(tt.in, &flagprinter) 1430 if s != tt.out { 1431 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out) 1432 } 1433 } 1434 } 1435 1436 func TestStructPrinter(t *testing.T) { 1437 type T struct { 1438 a string 1439 b string 1440 c int 1441 } 1442 var s T 1443 s.a = "abc" 1444 s.b = "def" 1445 s.c = 123 1446 var tests = []struct { 1447 fmt string 1448 out string 1449 }{ 1450 {"%v", "{abc def 123}"}, 1451 {"%+v", "{a:abc b:def c:123}"}, 1452 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`}, 1453 } 1454 for _, tt := range tests { 1455 out := Sprintf(tt.fmt, s) 1456 if out != tt.out { 1457 t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out) 1458 } 1459 // The same but with a pointer. 1460 out = Sprintf(tt.fmt, &s) 1461 if out != "&"+tt.out { 1462 t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out) 1463 } 1464 } 1465 } 1466 1467 func TestSlicePrinter(t *testing.T) { 1468 slice := []int{} 1469 s := Sprint(slice) 1470 if s != "[]" { 1471 t.Errorf("empty slice printed as %q not %q", s, "[]") 1472 } 1473 slice = []int{1, 2, 3} 1474 s = Sprint(slice) 1475 if s != "[1 2 3]" { 1476 t.Errorf("slice: got %q expected %q", s, "[1 2 3]") 1477 } 1478 s = Sprint(&slice) 1479 if s != "&[1 2 3]" { 1480 t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]") 1481 } 1482 } 1483 1484 // presentInMap checks map printing using substrings so we don't depend on the 1485 // print order. 1486 func presentInMap(s string, a []string, t *testing.T) { 1487 for i := 0; i < len(a); i++ { 1488 loc := strings.Index(s, a[i]) 1489 if loc < 0 { 1490 t.Errorf("map print: expected to find %q in %q", a[i], s) 1491 } 1492 // make sure the match ends here 1493 loc += len(a[i]) 1494 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') { 1495 t.Errorf("map print: %q not properly terminated in %q", a[i], s) 1496 } 1497 } 1498 } 1499 1500 func TestMapPrinter(t *testing.T) { 1501 m0 := make(map[int]string) 1502 s := Sprint(m0) 1503 if s != "map[]" { 1504 t.Errorf("empty map printed as %q not %q", s, "map[]") 1505 } 1506 m1 := map[int]string{1: "one", 2: "two", 3: "three"} 1507 a := []string{"1:one", "2:two", "3:three"} 1508 presentInMap(Sprintf("%v", m1), a, t) 1509 presentInMap(Sprint(m1), a, t) 1510 // Pointer to map prints the same but with initial &. 1511 if !strings.HasPrefix(Sprint(&m1), "&") { 1512 t.Errorf("no initial & for address of map") 1513 } 1514 presentInMap(Sprintf("%v", &m1), a, t) 1515 presentInMap(Sprint(&m1), a, t) 1516 } 1517 1518 func TestEmptyMap(t *testing.T) { 1519 const emptyMapStr = "map[]" 1520 var m map[string]int 1521 s := Sprint(m) 1522 if s != emptyMapStr { 1523 t.Errorf("nil map printed as %q not %q", s, emptyMapStr) 1524 } 1525 m = make(map[string]int) 1526 s = Sprint(m) 1527 if s != emptyMapStr { 1528 t.Errorf("empty map printed as %q not %q", s, emptyMapStr) 1529 } 1530 } 1531 1532 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the 1533 // right places, that is, between arg pairs in which neither is a string. 1534 func TestBlank(t *testing.T) { 1535 got := Sprint("<", 1, ">:", 1, 2, 3, "!") 1536 expect := "<1>:1 2 3!" 1537 if got != expect { 1538 t.Errorf("got %q expected %q", got, expect) 1539 } 1540 } 1541 1542 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in 1543 // the right places, that is, between all arg pairs. 1544 func TestBlankln(t *testing.T) { 1545 got := Sprintln("<", 1, ">:", 1, 2, 3, "!") 1546 expect := "< 1 >: 1 2 3 !\n" 1547 if got != expect { 1548 t.Errorf("got %q expected %q", got, expect) 1549 } 1550 } 1551 1552 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf. 1553 func TestFormatterPrintln(t *testing.T) { 1554 f := F(1) 1555 expect := "<v=F(1)>\n" 1556 s := Sprint(f, "\n") 1557 if s != expect { 1558 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s) 1559 } 1560 s = Sprintln(f) 1561 if s != expect { 1562 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s) 1563 } 1564 s = Sprintf("%v\n", f) 1565 if s != expect { 1566 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s) 1567 } 1568 } 1569 1570 func args(a ...interface{}) []interface{} { return a } 1571 1572 var startests = []struct { 1573 fmt string 1574 in []interface{} 1575 out string 1576 }{ 1577 {"%*d", args(4, 42), " 42"}, 1578 {"%-*d", args(4, 42), "42 "}, 1579 {"%*d", args(-4, 42), "42 "}, 1580 {"%-*d", args(-4, 42), "42 "}, 1581 {"%.*d", args(4, 42), "0042"}, 1582 {"%*.*d", args(8, 4, 42), " 0042"}, 1583 {"%0*d", args(4, 42), "0042"}, 1584 // Some non-int types for width. (Issue 10732). 1585 {"%0*d", args(uint(4), 42), "0042"}, 1586 {"%0*d", args(uint64(4), 42), "0042"}, 1587 {"%0*d", args('\x04', 42), "0042"}, 1588 {"%0*d", args(uintptr(4), 42), "0042"}, 1589 1590 // erroneous 1591 {"%*d", args(nil, 42), "%!(BADWIDTH)42"}, 1592 {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"}, 1593 {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"}, 1594 {"%.*d", args(nil, 42), "%!(BADPREC)42"}, 1595 {"%.*d", args(-1, 42), "%!(BADPREC)42"}, 1596 {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"}, 1597 {"%.*d", args(uint(1e7), 42), "%!(BADPREC)42"}, 1598 {"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"}, // Huge negative (-inf). 1599 {"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"}, // Small negative (-1). 1600 {"%*d", args(5, "foo"), "%!d(string= foo)"}, 1601 {"%*% %d", args(20, 5), "% 5"}, 1602 {"%*", args(4), "%!(NOVERB)"}, 1603 } 1604 1605 func TestWidthAndPrecision(t *testing.T) { 1606 for i, tt := range startests { 1607 s := Sprintf(tt.fmt, tt.in...) 1608 if s != tt.out { 1609 t.Errorf("#%d: %q: got %q expected %q", i, tt.fmt, s, tt.out) 1610 } 1611 } 1612 } 1613 1614 // PanicS is a type that panics in String. 1615 type PanicS struct { 1616 message interface{} 1617 } 1618 1619 // Value receiver. 1620 func (p PanicS) String() string { 1621 panic(p.message) 1622 } 1623 1624 // PanicGo is a type that panics in GoString. 1625 type PanicGo struct { 1626 message interface{} 1627 } 1628 1629 // Value receiver. 1630 func (p PanicGo) GoString() string { 1631 panic(p.message) 1632 } 1633 1634 // PanicF is a type that panics in Format. 1635 type PanicF struct { 1636 message interface{} 1637 } 1638 1639 // Value receiver. 1640 func (p PanicF) Format(f State, c rune) { 1641 panic(p.message) 1642 } 1643 1644 var panictests = []struct { 1645 fmt string 1646 in interface{} 1647 out string 1648 }{ 1649 // String 1650 {"%s", (*PanicS)(nil), "<nil>"}, // nil pointer special case 1651 {"%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 1652 {"%s", PanicS{3}, "%!s(PANIC=3)"}, 1653 // GoString 1654 {"%#v", (*PanicGo)(nil), "<nil>"}, // nil pointer special case 1655 {"%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"}, 1656 {"%#v", PanicGo{3}, "%!v(PANIC=3)"}, 1657 // Issue 18282. catchPanic should not clear fmtFlags permanently. 1658 {"%#v", []interface{}{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=3), %!v(PANIC=3)}"}, 1659 // Format 1660 {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case 1661 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 1662 {"%s", PanicF{3}, "%!s(PANIC=3)"}, 1663 } 1664 1665 func TestPanics(t *testing.T) { 1666 for i, tt := range panictests { 1667 s := Sprintf(tt.fmt, tt.in) 1668 if s != tt.out { 1669 t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out) 1670 } 1671 } 1672 } 1673 1674 // recurCount tests that erroneous String routine doesn't cause fatal recursion. 1675 var recurCount = 0 1676 1677 type Recur struct { 1678 i int 1679 failed *bool 1680 } 1681 1682 func (r *Recur) String() string { 1683 if recurCount++; recurCount > 10 { 1684 *r.failed = true 1685 return "FAIL" 1686 } 1687 // This will call badVerb. Before the fix, that would cause us to recur into 1688 // this routine to print %!p(value). Now we don't call the user's method 1689 // during an error. 1690 return Sprintf("recur@%p value: %d", r, r.i) 1691 } 1692 1693 func TestBadVerbRecursion(t *testing.T) { 1694 failed := false 1695 r := &Recur{3, &failed} 1696 Sprintf("recur@%p value: %d\n", &r, r.i) 1697 if failed { 1698 t.Error("fail with pointer") 1699 } 1700 failed = false 1701 r = &Recur{4, &failed} 1702 Sprintf("recur@%p, value: %d\n", r, r.i) 1703 if failed { 1704 t.Error("fail with value") 1705 } 1706 } 1707 1708 func TestIsSpace(t *testing.T) { 1709 // This tests the internal isSpace function. 1710 // IsSpace = isSpace is defined in export_test.go. 1711 for i := rune(0); i <= unicode.MaxRune; i++ { 1712 if IsSpace(i) != unicode.IsSpace(i) { 1713 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i)) 1714 } 1715 } 1716 } 1717 1718 func TestNilDoesNotBecomeTyped(t *testing.T) { 1719 type A struct{} 1720 type B struct{} 1721 var a *A = nil 1722 var b B = B{} 1723 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) // go vet should complain about this line. 1724 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)" 1725 if got != expect { 1726 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) 1727 } 1728 } 1729 1730 var formatterFlagTests = []struct { 1731 in string 1732 val interface{} 1733 out string 1734 }{ 1735 // scalar values with the (unused by fmt) 'a' verb. 1736 {"%a", flagPrinter{}, "[%a]"}, 1737 {"%-a", flagPrinter{}, "[%-a]"}, 1738 {"%+a", flagPrinter{}, "[%+a]"}, 1739 {"%#a", flagPrinter{}, "[%#a]"}, 1740 {"% a", flagPrinter{}, "[% a]"}, 1741 {"%0a", flagPrinter{}, "[%0a]"}, 1742 {"%1.2a", flagPrinter{}, "[%1.2a]"}, 1743 {"%-1.2a", flagPrinter{}, "[%-1.2a]"}, 1744 {"%+1.2a", flagPrinter{}, "[%+1.2a]"}, 1745 {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"}, 1746 {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"}, 1747 {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"}, 1748 1749 // composite values with the 'a' verb 1750 {"%a", [1]flagPrinter{}, "[[%a]]"}, 1751 {"%-a", [1]flagPrinter{}, "[[%-a]]"}, 1752 {"%+a", [1]flagPrinter{}, "[[%+a]]"}, 1753 {"%#a", [1]flagPrinter{}, "[[%#a]]"}, 1754 {"% a", [1]flagPrinter{}, "[[% a]]"}, 1755 {"%0a", [1]flagPrinter{}, "[[%0a]]"}, 1756 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"}, 1757 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"}, 1758 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"}, 1759 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"}, 1760 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"}, 1761 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"}, 1762 1763 // simple values with the 'v' verb 1764 {"%v", flagPrinter{}, "[%v]"}, 1765 {"%-v", flagPrinter{}, "[%-v]"}, 1766 {"%+v", flagPrinter{}, "[%+v]"}, 1767 {"%#v", flagPrinter{}, "[%#v]"}, 1768 {"% v", flagPrinter{}, "[% v]"}, 1769 {"%0v", flagPrinter{}, "[%0v]"}, 1770 {"%1.2v", flagPrinter{}, "[%1.2v]"}, 1771 {"%-1.2v", flagPrinter{}, "[%-1.2v]"}, 1772 {"%+1.2v", flagPrinter{}, "[%+1.2v]"}, 1773 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"}, 1774 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"}, 1775 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"}, 1776 1777 // composite values with the 'v' verb. 1778 {"%v", [1]flagPrinter{}, "[[%v]]"}, 1779 {"%-v", [1]flagPrinter{}, "[[%-v]]"}, 1780 {"%+v", [1]flagPrinter{}, "[[%+v]]"}, 1781 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"}, 1782 {"% v", [1]flagPrinter{}, "[[% v]]"}, 1783 {"%0v", [1]flagPrinter{}, "[[%0v]]"}, 1784 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"}, 1785 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"}, 1786 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"}, 1787 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"}, 1788 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"}, 1789 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"}, 1790 } 1791 1792 func TestFormatterFlags(t *testing.T) { 1793 for _, tt := range formatterFlagTests { 1794 s := Sprintf(tt.in, tt.val) 1795 if s != tt.out { 1796 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out) 1797 } 1798 } 1799 } 1800 1801 func TestParsenum(t *testing.T) { 1802 testCases := []struct { 1803 s string 1804 start, end int 1805 num int 1806 isnum bool 1807 newi int 1808 }{ 1809 {"a123", 0, 4, 0, false, 0}, 1810 {"1234", 1, 1, 0, false, 1}, 1811 {"123a", 0, 4, 123, true, 3}, 1812 {"12a3", 0, 4, 12, true, 2}, 1813 {"1234", 0, 4, 1234, true, 4}, 1814 {"1a234", 1, 3, 0, false, 1}, 1815 } 1816 for _, tt := range testCases { 1817 num, isnum, newi := Parsenum(tt.s, tt.start, tt.end) 1818 if num != tt.num || isnum != tt.isnum || newi != tt.newi { 1819 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) 1820 } 1821 } 1822 }