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