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