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