rsc.io/go@v0.0.0-20150416155037-e040fd465409/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 "io" 11 "math" 12 "reflect" 13 "runtime" 14 "strings" 15 "testing" 16 "time" 17 "unicode" 18 ) 19 20 type ( 21 renamedBool bool 22 renamedInt int 23 renamedInt8 int8 24 renamedInt16 int16 25 renamedInt32 int32 26 renamedInt64 int64 27 renamedUint uint 28 renamedUint8 uint8 29 renamedUint16 uint16 30 renamedUint32 uint32 31 renamedUint64 uint64 32 renamedUintptr uintptr 33 renamedString string 34 renamedBytes []byte 35 renamedFloat32 float32 36 renamedFloat64 float64 37 renamedComplex64 complex64 38 renamedComplex128 complex128 39 ) 40 41 func TestFmtInterface(t *testing.T) { 42 var i1 interface{} 43 i1 = "abc" 44 s := Sprintf("%s", i1) 45 if s != "abc" { 46 t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc") 47 } 48 } 49 50 const b32 uint32 = 1<<32 - 1 51 const b64 uint64 = 1<<64 - 1 52 53 var array = [5]int{1, 2, 3, 4, 5} 54 var iarray = [4]interface{}{1, "hello", 2.5, nil} 55 var slice = array[:] 56 var islice = iarray[:] 57 58 type A struct { 59 i int 60 j uint 61 s string 62 x []int 63 } 64 65 type I int 66 67 func (i I) String() string { return Sprintf("<%d>", int(i)) } 68 69 type B struct { 70 I I 71 j int 72 } 73 74 type C struct { 75 i int 76 B 77 } 78 79 type F int 80 81 func (f F) Format(s State, c rune) { 82 Fprintf(s, "<%c=F(%d)>", c, int(f)) 83 } 84 85 type G int 86 87 func (g G) GoString() string { 88 return Sprintf("GoString(%d)", int(g)) 89 } 90 91 type S struct { 92 F F // a struct field that Formats 93 G G // a struct field that GoStrings 94 } 95 96 type SI struct { 97 I interface{} 98 } 99 100 // P is a type with a String method with pointer receiver for testing %p. 101 type P int 102 103 var pValue P 104 105 func (p *P) String() string { 106 return "String(p)" 107 } 108 109 var barray = [5]renamedUint8{1, 2, 3, 4, 5} 110 var bslice = barray[:] 111 112 type byteStringer byte 113 114 func (byteStringer) String() string { return "X" } 115 116 var byteStringerSlice = []byteStringer{97, 98, 99, 100} 117 118 type byteFormatter byte 119 120 func (byteFormatter) Format(f State, _ rune) { 121 Fprint(f, "X") 122 } 123 124 var byteFormatterSlice = []byteFormatter{97, 98, 99, 100} 125 126 var b byte 127 128 var fmtTests = []struct { 129 fmt string 130 val interface{} 131 out string 132 }{ 133 {"%d", 12345, "12345"}, 134 {"%v", 12345, "12345"}, 135 {"%t", true, "true"}, 136 137 // basic string 138 {"%s", "abc", "abc"}, 139 {"%q", "abc", `"abc"`}, 140 {"%x", "abc", "616263"}, 141 {"%x", "\xff\xf0\x0f\xff", "fff00fff"}, 142 {"%X", "\xff\xf0\x0f\xff", "FFF00FFF"}, 143 {"%x", "xyz", "78797a"}, 144 {"%X", "xyz", "78797A"}, 145 {"% x", "xyz", "78 79 7a"}, 146 {"% X", "xyz", "78 79 7A"}, 147 {"%#x", "xyz", "0x78797a"}, 148 {"%#X", "xyz", "0X78797A"}, 149 {"%# x", "xyz", "0x78 0x79 0x7a"}, 150 {"%# X", "xyz", "0X78 0X79 0X7A"}, 151 152 // basic bytes 153 {"%s", []byte("abc"), "abc"}, 154 {"%q", []byte("abc"), `"abc"`}, 155 {"%x", []byte("abc"), "616263"}, 156 {"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"}, 157 {"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"}, 158 {"%x", []byte("xyz"), "78797a"}, 159 {"%X", []byte("xyz"), "78797A"}, 160 {"% x", []byte("xyz"), "78 79 7a"}, 161 {"% X", []byte("xyz"), "78 79 7A"}, 162 {"%#x", []byte("xyz"), "0x78797a"}, 163 {"%#X", []byte("xyz"), "0X78797A"}, 164 {"%# x", []byte("xyz"), "0x78 0x79 0x7a"}, 165 {"%# X", []byte("xyz"), "0X78 0X79 0X7A"}, 166 167 // escaped strings 168 {"%#q", `abc`, "`abc`"}, 169 {"%#q", `"`, "`\"`"}, 170 {"1 %#q", `\n`, "1 `\\n`"}, 171 {"2 %#q", "\n", `2 "\n"`}, 172 {"%q", `"`, `"\""`}, 173 {"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`}, 174 {"%q", "abc\xffdef", `"abc\xffdef"`}, 175 {"%q", "\u263a", `"☺"`}, 176 {"%+q", "\u263a", `"\u263a"`}, 177 {"%q", "\U0010ffff", `"\U0010ffff"`}, 178 179 // escaped characters 180 {"%q", 'x', `'x'`}, 181 {"%q", 0, `'\x00'`}, 182 {"%q", '\n', `'\n'`}, 183 {"%q", '\u0e00', `'\u0e00'`}, // not a printable rune. 184 {"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune. 185 {"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`}, 186 {"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`}, 187 {"%q", '"', `'"'`}, 188 {"%q", '\'', `'\''`}, 189 {"%q", "\u263a", `"☺"`}, 190 {"%+q", "\u263a", `"\u263a"`}, 191 192 // width 193 {"%5s", "abc", " abc"}, 194 {"%2s", "\u263a", " ☺"}, 195 {"%-5s", "abc", "abc "}, 196 {"%-8q", "abc", `"abc" `}, 197 {"%05s", "abc", "00abc"}, 198 {"%08q", "abc", `000"abc"`}, 199 {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"}, 200 {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"}, 201 {"%.5s", "日本語日本語", "日本語日本"}, 202 {"%.5s", []byte("日本語日本語"), "日本語日本"}, 203 {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`}, 204 {"%.5x", "abcdefghijklmnopqrstuvwxyz", `6162636465`}, 205 {"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`}, 206 {"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), `6162636465`}, 207 {"%.3q", "日本語日本語", `"日本語"`}, 208 {"%.3q", []byte("日本語日本語"), `"日本語"`}, 209 {"%.1q", "日本語", `"日"`}, 210 {"%.1q", []byte("日本語"), `"日"`}, 211 {"%.1x", "日本語", `e6`}, 212 {"%.1X", []byte("日本語"), `E6`}, 213 {"%10.1q", "日本語日本語", ` "日"`}, 214 {"%3c", '⌘', " ⌘"}, 215 {"%5q", '\u2026', ` '…'`}, 216 {"%10v", nil, " <nil>"}, 217 {"%-10v", nil, "<nil> "}, 218 219 // integers 220 {"%d", 12345, "12345"}, 221 {"%d", -12345, "-12345"}, 222 {"%10d", 12345, " 12345"}, 223 {"%10d", -12345, " -12345"}, 224 {"%+10d", 12345, " +12345"}, 225 {"%010d", 12345, "0000012345"}, 226 {"%010d", -12345, "-000012345"}, 227 {"%-10d", 12345, "12345 "}, 228 {"%010.3d", 1, " 001"}, 229 {"%010.3d", -1, " -001"}, 230 {"%+d", 12345, "+12345"}, 231 {"%+d", -12345, "-12345"}, 232 {"%+d", 0, "+0"}, 233 {"% d", 0, " 0"}, 234 {"% d", 12345, " 12345"}, 235 {"%.0d", 0, ""}, 236 {"%.d", 0, ""}, 237 238 // unicode format 239 {"%U", 0x1, "U+0001"}, 240 {"%U", uint(0x1), "U+0001"}, 241 {"%.8U", 0x2, "U+00000002"}, 242 {"%U", 0x1234, "U+1234"}, 243 {"%U", 0x12345, "U+12345"}, 244 {"%10.6U", 0xABC, " U+000ABC"}, 245 {"%-10.6U", 0xABC, "U+000ABC "}, 246 {"%U", '\n', `U+000A`}, 247 {"%#U", '\n', `U+000A`}, 248 {"%U", 'x', `U+0078`}, 249 {"%#U", 'x', `U+0078 'x'`}, 250 {"%U", '\u263a', `U+263A`}, 251 {"%#U", '\u263a', `U+263A '☺'`}, 252 253 // floats 254 {"%+.3e", 0.0, "+0.000e+00"}, 255 {"%+.3e", 1.0, "+1.000e+00"}, 256 {"%+.3f", -1.0, "-1.000"}, 257 {"%+.3F", -1.0, "-1.000"}, 258 {"%+.3F", float32(-1.0), "-1.000"}, 259 {"%+07.2f", 1.0, "+001.00"}, 260 {"%+07.2f", -1.0, "-001.00"}, 261 {"%+10.2f", +1.0, " +1.00"}, 262 {"%+10.2f", -1.0, " -1.00"}, 263 {"% .3E", -1.0, "-1.000E+00"}, 264 {"% .3e", 1.0, " 1.000e+00"}, 265 {"%+.3g", 0.0, "+0"}, 266 {"%+.3g", 1.0, "+1"}, 267 {"%+.3g", -1.0, "-1"}, 268 {"% .3g", -1.0, "-1"}, 269 {"% .3g", 1.0, " 1"}, 270 {"%b", float32(1.0), "8388608p-23"}, 271 {"%b", 1.0, "4503599627370496p-52"}, 272 273 // complex values 274 {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"}, 275 {"%+.3f", 0i, "(+0.000+0.000i)"}, 276 {"%+.3g", 0i, "(+0+0i)"}, 277 {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"}, 278 {"%+.3f", 1 + 2i, "(+1.000+2.000i)"}, 279 {"%+.3g", 1 + 2i, "(+1+2i)"}, 280 {"%.3e", 0i, "(0.000e+00+0.000e+00i)"}, 281 {"%.3f", 0i, "(0.000+0.000i)"}, 282 {"%.3F", 0i, "(0.000+0.000i)"}, 283 {"%.3F", complex64(0i), "(0.000+0.000i)"}, 284 {"%.3g", 0i, "(0+0i)"}, 285 {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"}, 286 {"%.3f", 1 + 2i, "(1.000+2.000i)"}, 287 {"%.3g", 1 + 2i, "(1+2i)"}, 288 {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"}, 289 {"%.3f", -1 - 2i, "(-1.000-2.000i)"}, 290 {"%.3g", -1 - 2i, "(-1-2i)"}, 291 {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"}, 292 {"%+.3g", complex64(1 + 2i), "(+1+2i)"}, 293 {"%+.3g", complex128(1 + 2i), "(+1+2i)"}, 294 {"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"}, 295 {"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"}, 296 297 // erroneous formats 298 {"", 2, "%!(EXTRA int=2)"}, 299 {"%d", "hello", "%!d(string=hello)"}, 300 301 // old test/fmt_test.go 302 {"%d", 1234, "1234"}, 303 {"%d", -1234, "-1234"}, 304 {"%d", uint(1234), "1234"}, 305 {"%d", uint32(b32), "4294967295"}, 306 {"%d", uint64(b64), "18446744073709551615"}, 307 {"%o", 01234, "1234"}, 308 {"%#o", 01234, "01234"}, 309 {"%o", uint32(b32), "37777777777"}, 310 {"%o", uint64(b64), "1777777777777777777777"}, 311 {"%x", 0x1234abcd, "1234abcd"}, 312 {"%#x", 0x1234abcd, "0x1234abcd"}, 313 {"%x", b32 - 0x1234567, "fedcba98"}, 314 {"%X", 0x1234abcd, "1234ABCD"}, 315 {"%X", b32 - 0x1234567, "FEDCBA98"}, 316 {"%#X", 0, "0X0"}, 317 {"%x", b64, "ffffffffffffffff"}, 318 {"%b", 7, "111"}, 319 {"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"}, 320 {"%b", -6, "-110"}, 321 {"%e", 1.0, "1.000000e+00"}, 322 {"%e", 1234.5678e3, "1.234568e+06"}, 323 {"%e", 1234.5678e-8, "1.234568e-05"}, 324 {"%e", -7.0, "-7.000000e+00"}, 325 {"%e", -1e-9, "-1.000000e-09"}, 326 {"%f", 1234.5678e3, "1234567.800000"}, 327 {"%f", 1234.5678e-8, "0.000012"}, 328 {"%f", -7.0, "-7.000000"}, 329 {"%f", -1e-9, "-0.000000"}, 330 {"%g", 1234.5678e3, "1.2345678e+06"}, 331 {"%g", float32(1234.5678e3), "1.2345678e+06"}, 332 {"%g", 1234.5678e-8, "1.2345678e-05"}, 333 {"%g", -7.0, "-7"}, 334 {"%g", -1e-9, "-1e-09"}, 335 {"%g", float32(-1e-9), "-1e-09"}, 336 {"%E", 1.0, "1.000000E+00"}, 337 {"%E", 1234.5678e3, "1.234568E+06"}, 338 {"%E", 1234.5678e-8, "1.234568E-05"}, 339 {"%E", -7.0, "-7.000000E+00"}, 340 {"%E", -1e-9, "-1.000000E-09"}, 341 {"%G", 1234.5678e3, "1.2345678E+06"}, 342 {"%G", float32(1234.5678e3), "1.2345678E+06"}, 343 {"%G", 1234.5678e-8, "1.2345678E-05"}, 344 {"%G", -7.0, "-7"}, 345 {"%G", -1e-9, "-1E-09"}, 346 {"%G", float32(-1e-9), "-1E-09"}, 347 {"%c", 'x', "x"}, 348 {"%c", 0xe4, "ä"}, 349 {"%c", 0x672c, "本"}, 350 {"%c", '日', "日"}, 351 {"%20.8d", 1234, " 00001234"}, 352 {"%20.8d", -1234, " -00001234"}, 353 {"%20d", 1234, " 1234"}, 354 {"%-20.8d", 1234, "00001234 "}, 355 {"%-20.8d", -1234, "-00001234 "}, 356 {"%-#20.8x", 0x1234abc, "0x01234abc "}, 357 {"%-#20.8X", 0x1234abc, "0X01234ABC "}, 358 {"%-#20.8o", 01234, "00001234 "}, 359 {"%.20b", 7, "00000000000000000111"}, 360 {"%20.5s", "qwertyuiop", " qwert"}, 361 {"%.5s", "qwertyuiop", "qwert"}, 362 {"%-20.5s", "qwertyuiop", "qwert "}, 363 {"%20c", 'x', " x"}, 364 {"%-20c", 'x', "x "}, 365 {"%20.6e", 1.2345e3, " 1.234500e+03"}, 366 {"%20.6e", 1.2345e-3, " 1.234500e-03"}, 367 {"%20e", 1.2345e3, " 1.234500e+03"}, 368 {"%20e", 1.2345e-3, " 1.234500e-03"}, 369 {"%20.8e", 1.2345e3, " 1.23450000e+03"}, 370 {"%20f", 1.23456789e3, " 1234.567890"}, 371 {"%20f", 1.23456789e-3, " 0.001235"}, 372 {"%20f", 12345678901.23456789, " 12345678901.234568"}, 373 {"%-20f", 1.23456789e3, "1234.567890 "}, 374 {"%20.8f", 1.23456789e3, " 1234.56789000"}, 375 {"%20.8f", 1.23456789e-3, " 0.00123457"}, 376 {"%g", 1.23456789e3, "1234.56789"}, 377 {"%g", 1.23456789e-3, "0.00123456789"}, 378 {"%g", 1.23456789e20, "1.23456789e+20"}, 379 {"%20e", math.Inf(1), " +Inf"}, 380 {"%-20f", math.Inf(-1), "-Inf "}, 381 {"%20g", math.NaN(), " NaN"}, 382 383 // arrays 384 {"%v", array, "[1 2 3 4 5]"}, 385 {"%v", iarray, "[1 hello 2.5 <nil>]"}, 386 {"%v", barray, "[1 2 3 4 5]"}, 387 {"%v", &array, "&[1 2 3 4 5]"}, 388 {"%v", &iarray, "&[1 hello 2.5 <nil>]"}, 389 {"%v", &barray, "&[1 2 3 4 5]"}, 390 391 // slices 392 {"%v", slice, "[1 2 3 4 5]"}, 393 {"%v", islice, "[1 hello 2.5 <nil>]"}, 394 {"%v", bslice, "[1 2 3 4 5]"}, 395 {"%v", &slice, "&[1 2 3 4 5]"}, 396 {"%v", &islice, "&[1 hello 2.5 <nil>]"}, 397 {"%v", &bslice, "&[1 2 3 4 5]"}, 398 {"%v", []byte{1}, "[1]"}, 399 {"%v", []byte{}, "[]"}, 400 401 // complexes with %v 402 {"%v", 1 + 2i, "(1+2i)"}, 403 {"%v", complex64(1 + 2i), "(1+2i)"}, 404 {"%v", complex128(1 + 2i), "(1+2i)"}, 405 406 // structs 407 {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`}, 408 {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`}, 409 410 // +v on structs with Stringable items 411 {"%+v", B{1, 2}, `{I:<1> j:2}`}, 412 {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`}, 413 414 // other formats on Stringable items 415 {"%s", I(23), `<23>`}, 416 {"%q", I(23), `"<23>"`}, 417 {"%x", I(23), `3c32333e`}, 418 {"%#x", I(23), `0x3c32333e`}, 419 {"%# x", I(23), `0x3c 0x32 0x33 0x3e`}, 420 {"%d", I(23), `23`}, // Stringer applies only to string formats. 421 422 // go syntax 423 {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`}, 424 {"%#v", &b, "(*uint8)(0xPTR)"}, 425 {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"}, 426 {"%#v", make(chan int), "(chan int)(0xPTR)"}, 427 {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"}, 428 {"%#v", 1000000000, "1000000000"}, 429 {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`}, 430 {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`}, 431 {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`}, 432 {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`}, 433 {"%#v", []int(nil), `[]int(nil)`}, 434 {"%#v", []int{}, `[]int{}`}, 435 {"%#v", array, `[5]int{1, 2, 3, 4, 5}`}, 436 {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`}, 437 {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`}, 438 {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`}, 439 {"%#v", map[int]byte(nil), `map[int]uint8(nil)`}, 440 {"%#v", map[int]byte{}, `map[int]uint8{}`}, 441 {"%#v", "foo", `"foo"`}, 442 {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`}, 443 {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`}, 444 {"%#v", []byte(nil), "[]byte(nil)"}, 445 {"%#v", []int32(nil), "[]int32(nil)"}, 446 447 // slices with other formats 448 {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`}, 449 {"%x", []int{1, 2, 15}, `[1 2 f]`}, 450 {"%d", []int{1, 2, 15}, `[1 2 15]`}, 451 {"%d", []byte{1, 2, 15}, `[1 2 15]`}, 452 {"%q", []string{"a", "b"}, `["a" "b"]`}, 453 {"% 02x", []byte{1}, "01"}, 454 {"% 02x", []byte{1, 2, 3}, "01 02 03"}, 455 // Special care for empty slices. 456 {"%x", []byte{}, ""}, 457 {"%02x", []byte{}, ""}, 458 {"% 02x", []byte{}, ""}, 459 460 // renamings 461 {"%v", renamedBool(true), "true"}, 462 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"}, 463 {"%o", renamedInt(8), "10"}, 464 {"%d", renamedInt8(-9), "-9"}, 465 {"%v", renamedInt16(10), "10"}, 466 {"%v", renamedInt32(-11), "-11"}, 467 {"%X", renamedInt64(255), "FF"}, 468 {"%v", renamedUint(13), "13"}, 469 {"%o", renamedUint8(14), "16"}, 470 {"%X", renamedUint16(15), "F"}, 471 {"%d", renamedUint32(16), "16"}, 472 {"%X", renamedUint64(17), "11"}, 473 {"%o", renamedUintptr(18), "22"}, 474 {"%x", renamedString("thing"), "7468696e67"}, 475 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`}, 476 {"%q", renamedBytes([]byte("hello")), `"hello"`}, 477 {"%x", []renamedUint8{'a', 'b', 'c'}, "616263"}, 478 {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"}, 479 {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`}, 480 {"%v", renamedFloat32(22), "22"}, 481 {"%v", renamedFloat64(33), "33"}, 482 {"%v", renamedComplex64(3 + 4i), "(3+4i)"}, 483 {"%v", renamedComplex128(4 - 3i), "(4-3i)"}, 484 485 // Formatter 486 {"%x", F(1), "<x=F(1)>"}, 487 {"%x", G(2), "2"}, 488 {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"}, 489 490 // GoStringer 491 {"%#v", G(6), "GoString(6)"}, 492 {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"}, 493 494 // %T 495 {"%T", (4 - 3i), "complex128"}, 496 {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"}, 497 {"%T", intVal, "int"}, 498 {"%6T", &intVal, " *int"}, 499 {"%10T", nil, " <nil>"}, 500 {"%-10T", nil, "<nil> "}, 501 502 // %p 503 {"p0=%p", new(int), "p0=0xPTR"}, 504 {"p1=%s", &pValue, "p1=String(p)"}, // String method... 505 {"p2=%p", &pValue, "p2=0xPTR"}, // ... not called with %p 506 {"p3=%p", (*int)(nil), "p3=0x0"}, 507 {"p4=%#p", new(int), "p4=PTR"}, 508 509 // %p on non-pointers 510 {"%p", make(chan int), "0xPTR"}, 511 {"%p", make(map[int]int), "0xPTR"}, 512 {"%p", make([]int, 1), "0xPTR"}, 513 {"%p", 27, "%!p(int=27)"}, // not a pointer at all 514 515 // %q on pointers 516 {"%q", (*int)(nil), "%!q(*int=<nil>)"}, 517 {"%q", new(int), "%!q(*int=0xPTR)"}, 518 519 // %v on pointers formats 0 as <nil> 520 {"%v", (*int)(nil), "<nil>"}, 521 {"%v", new(int), "0xPTR"}, 522 523 // %d etc. pointers use specified base. 524 {"%d", new(int), "PTR_d"}, 525 {"%o", new(int), "PTR_o"}, 526 {"%x", new(int), "PTR_x"}, 527 528 // %d on Stringer should give integer if possible 529 {"%s", time.Time{}.Month(), "January"}, 530 {"%d", time.Time{}.Month(), "1"}, 531 532 // erroneous things 533 {"%s %", "hello", "hello %!(NOVERB)"}, 534 {"%s %.2", "hello", "hello %!(NOVERB)"}, 535 {"%d", "hello", "%!d(string=hello)"}, 536 {"no args", "hello", "no args%!(EXTRA string=hello)"}, 537 {"%s", nil, "%!s(<nil>)"}, 538 {"%T", nil, "<nil>"}, 539 {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"}, 540 541 // The "<nil>" show up because maps are printed by 542 // first obtaining a list of keys and then looking up 543 // each key. Since NaNs can be map keys but cannot 544 // be fetched directly, the lookup fails and returns a 545 // zero reflect.Value, which formats as <nil>. 546 // This test is just to check that it shows the two NaNs at all. 547 {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"}, 548 549 // Used to crash because nByte didn't allow for a sign. 550 {"%b", int64(-1 << 63), zeroFill("-1", 63, "")}, 551 552 // Used to panic. 553 {"%0100d", 1, zeroFill("", 100, "1")}, 554 {"%0100d", -1, zeroFill("-", 99, "1")}, 555 {"%0.100f", 1.0, zeroFill("1.", 100, "")}, 556 {"%0.100f", -1.0, zeroFill("-1.", 100, "")}, 557 558 // Comparison of padding rules with C printf. 559 /* 560 C program: 561 #include <stdio.h> 562 563 char *format[] = { 564 "[%.2f]", 565 "[% .2f]", 566 "[%+.2f]", 567 "[%7.2f]", 568 "[% 7.2f]", 569 "[%+7.2f]", 570 "[%07.2f]", 571 "[% 07.2f]", 572 "[%+07.2f]", 573 }; 574 575 int main(void) { 576 int i; 577 for(i = 0; i < 9; i++) { 578 printf("%s: ", format[i]); 579 printf(format[i], 1.0); 580 printf(" "); 581 printf(format[i], -1.0); 582 printf("\n"); 583 } 584 } 585 586 Output: 587 [%.2f]: [1.00] [-1.00] 588 [% .2f]: [ 1.00] [-1.00] 589 [%+.2f]: [+1.00] [-1.00] 590 [%7.2f]: [ 1.00] [ -1.00] 591 [% 7.2f]: [ 1.00] [ -1.00] 592 [%+7.2f]: [ +1.00] [ -1.00] 593 [%07.2f]: [0001.00] [-001.00] 594 [% 07.2f]: [ 001.00] [-001.00] 595 [%+07.2f]: [+001.00] [-001.00] 596 */ 597 {"%.2f", 1.0, "1.00"}, 598 {"%.2f", -1.0, "-1.00"}, 599 {"% .2f", 1.0, " 1.00"}, 600 {"% .2f", -1.0, "-1.00"}, 601 {"%+.2f", 1.0, "+1.00"}, 602 {"%+.2f", -1.0, "-1.00"}, 603 {"%7.2f", 1.0, " 1.00"}, 604 {"%7.2f", -1.0, " -1.00"}, 605 {"% 7.2f", 1.0, " 1.00"}, 606 {"% 7.2f", -1.0, " -1.00"}, 607 {"%+7.2f", 1.0, " +1.00"}, 608 {"%+7.2f", -1.0, " -1.00"}, 609 {"%07.2f", 1.0, "0001.00"}, 610 {"%07.2f", -1.0, "-001.00"}, 611 {"% 07.2f", 1.0, " 001.00"}, 612 {"% 07.2f", -1.0, "-001.00"}, 613 {"%+07.2f", 1.0, "+001.00"}, 614 {"%+07.2f", -1.0, "-001.00"}, 615 616 // Complex numbers: exhaustively tested in TestComplexFormatting. 617 {"%7.2f", 1 + 2i, "( 1.00 +2.00i)"}, 618 {"%+07.2f", -1 - 2i, "(-001.00-002.00i)"}, 619 // Zero padding does not apply to infinities. 620 {"%020f", math.Inf(-1), " -Inf"}, 621 {"%020f", math.Inf(+1), " +Inf"}, 622 {"% 020f", math.Inf(-1), " -Inf"}, 623 {"% 020f", math.Inf(+1), " Inf"}, 624 {"%+020f", math.Inf(-1), " -Inf"}, 625 {"%+020f", math.Inf(+1), " +Inf"}, 626 {"%20f", -1.0, " -1.000000"}, 627 // Make sure we can handle very large widths. 628 {"%0100f", -1.0, zeroFill("-", 99, "1.000000")}, 629 630 // Complex fmt used to leave the plus flag set for future entries in the array 631 // causing +2+0i and +3+0i instead of 2+0i and 3+0i. 632 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, 633 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, 634 635 // Incomplete format specification caused crash. 636 {"%.", 3, "%!.(int=3)"}, 637 638 // Used to panic with out-of-bounds for very large numeric representations. 639 // nByte is set to handle one bit per uint64 in %b format, with a negative number. 640 // See issue 6777. 641 {"%#064x", 1, zeroFill("0x", 64, "1")}, 642 {"%#064x", -1, zeroFill("-0x", 63, "1")}, 643 {"%#064b", 1, zeroFill("", 64, "1")}, 644 {"%#064b", -1, zeroFill("-", 63, "1")}, 645 {"%#064o", 1, zeroFill("", 64, "1")}, 646 {"%#064o", -1, zeroFill("-", 63, "1")}, 647 {"%#064d", 1, zeroFill("", 64, "1")}, 648 {"%#064d", -1, zeroFill("-", 63, "1")}, 649 // Test that we handle the crossover above the size of uint64 650 {"%#072x", 1, zeroFill("0x", 72, "1")}, 651 {"%#072x", -1, zeroFill("-0x", 71, "1")}, 652 {"%#072b", 1, zeroFill("", 72, "1")}, 653 {"%#072b", -1, zeroFill("-", 71, "1")}, 654 {"%#072o", 1, zeroFill("", 72, "1")}, 655 {"%#072o", -1, zeroFill("-", 71, "1")}, 656 {"%#072d", 1, zeroFill("", 72, "1")}, 657 {"%#072d", -1, zeroFill("-", 71, "1")}, 658 659 // Padding for complex numbers. Has been bad, then fixed, then bad again. 660 {"%+10.2f", +104.66 + 440.51i, "( +104.66 +440.51i)"}, 661 {"%+10.2f", -104.66 + 440.51i, "( -104.66 +440.51i)"}, 662 {"%+10.2f", +104.66 - 440.51i, "( +104.66 -440.51i)"}, 663 {"%+10.2f", -104.66 - 440.51i, "( -104.66 -440.51i)"}, 664 {"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"}, 665 {"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"}, 666 {"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"}, 667 {"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"}, 668 669 // []T where type T is a byte with a Stringer method. 670 {"%v", byteStringerSlice, "[X X X X]"}, 671 {"%s", byteStringerSlice, "abcd"}, 672 {"%q", byteStringerSlice, "\"abcd\""}, 673 {"%x", byteStringerSlice, "61626364"}, 674 {"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x61, 0x62, 0x63, 0x64}"}, 675 676 // And the same for Formatter. 677 {"%v", byteFormatterSlice, "[X X X X]"}, 678 {"%s", byteFormatterSlice, "abcd"}, 679 {"%q", byteFormatterSlice, "\"abcd\""}, 680 {"%x", byteFormatterSlice, "61626364"}, 681 // This next case seems wrong, but the docs say the Formatter wins here. 682 {"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X}"}, 683 684 // reflect.Value handled specially in Go 1.5, making it possible to 685 // see inside non-exported fields (which cannot be accessed with Interface()). 686 // Issue 8965. 687 {"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"}, // Equivalent to the old way. 688 {"%v", reflect.ValueOf(A{}).Field(0), "0"}, // Sees inside the field. 689 } 690 691 // zeroFill generates zero-filled strings of the specified width. The length 692 // of the suffix (but not the prefix) is compensated for in the width calculation. 693 func zeroFill(prefix string, width int, suffix string) string { 694 return prefix + strings.Repeat("0", width-len(suffix)) + suffix 695 } 696 697 func TestSprintf(t *testing.T) { 698 for _, tt := range fmtTests { 699 s := Sprintf(tt.fmt, tt.val) 700 if i := strings.Index(tt.out, "PTR"); i >= 0 { 701 pattern := "PTR" 702 chars := "0123456789abcdefABCDEF" 703 switch { 704 case strings.HasPrefix(tt.out[i:], "PTR_d"): 705 pattern = "PTR_d" 706 chars = chars[:10] 707 case strings.HasPrefix(tt.out[i:], "PTR_o"): 708 pattern = "PTR_o" 709 chars = chars[:8] 710 case strings.HasPrefix(tt.out[i:], "PTR_x"): 711 pattern = "PTR_x" 712 } 713 j := i 714 for ; j < len(s); j++ { 715 c := s[j] 716 if !strings.ContainsRune(chars, rune(c)) { 717 break 718 } 719 } 720 s = s[0:i] + pattern + s[j:] 721 } 722 if s != tt.out { 723 if _, ok := tt.val.(string); ok { 724 // Don't requote the already-quoted strings. 725 // It's too confusing to read the errors. 726 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out) 727 } else { 728 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out) 729 } 730 } 731 } 732 } 733 734 // TestComplexFormatting checks that a complex always formats to the same 735 // thing as if done by hand with two singleton prints. 736 func TestComplexFormatting(t *testing.T) { 737 var yesNo = []bool{true, false} 738 var values = []float64{1, 0, -1, math.Inf(1), math.Inf(-1), math.NaN()} 739 for _, plus := range yesNo { 740 for _, zero := range yesNo { 741 for _, space := range yesNo { 742 for _, char := range "fFeEgG" { 743 realFmt := "%" 744 if zero { 745 realFmt += "0" 746 } 747 if space { 748 realFmt += " " 749 } 750 if plus { 751 realFmt += "+" 752 } 753 realFmt += "10.2" 754 realFmt += string(char) 755 // Imaginary part always has a sign, so force + and ignore space. 756 imagFmt := "%" 757 if zero { 758 imagFmt += "0" 759 } 760 imagFmt += "+" 761 imagFmt += "10.2" 762 imagFmt += string(char) 763 for _, realValue := range values { 764 for _, imagValue := range values { 765 one := Sprintf(realFmt, complex(realValue, imagValue)) 766 two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue) 767 if one != two { 768 t.Error(f, one, two) 769 } 770 } 771 } 772 } 773 } 774 } 775 } 776 } 777 778 type SE []interface{} // slice of empty; notational compactness. 779 780 var reorderTests = []struct { 781 fmt string 782 val SE 783 out string 784 }{ 785 {"%[1]d", SE{1}, "1"}, 786 {"%[2]d", SE{2, 1}, "1"}, 787 {"%[2]d %[1]d", SE{1, 2}, "2 1"}, 788 {"%[2]*[1]d", SE{2, 5}, " 2"}, 789 {"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line. 790 {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"}, 791 {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"}, 792 {"%10f", SE{12.0}, " 12.000000"}, 793 {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"}, 794 {"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line. 795 {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"}, 796 {"%6.f", SE{12.0}, " 12"}, // // Explicit version of next line; empty precision means zero. 797 {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"}, 798 // An actual use! Print the same arguments twice. 799 {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"}, 800 801 // Erroneous cases. 802 {"%[d", SE{2, 1}, "%!d(BADINDEX)"}, 803 {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"}, 804 {"%[]d", SE{2, 1}, "%!d(BADINDEX)"}, 805 {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"}, 806 {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"}, 807 {"%[3]", SE{2, 1}, "%!(NOVERB)"}, 808 {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"}, 809 {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"}, 810 {"%3.[2]d", SE{7}, "%!d(BADINDEX)"}, 811 {"%.[2]d", SE{7}, "%!d(BADINDEX)"}, 812 {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"}, 813 {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"}, 814 {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence. 815 } 816 817 func TestReorder(t *testing.T) { 818 for _, tt := range reorderTests { 819 s := Sprintf(tt.fmt, tt.val...) 820 if s != tt.out { 821 t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out) 822 } else { 823 } 824 } 825 } 826 827 func BenchmarkSprintfEmpty(b *testing.B) { 828 b.RunParallel(func(pb *testing.PB) { 829 for pb.Next() { 830 Sprintf("") 831 } 832 }) 833 } 834 835 func BenchmarkSprintfString(b *testing.B) { 836 b.RunParallel(func(pb *testing.PB) { 837 for pb.Next() { 838 Sprintf("%s", "hello") 839 } 840 }) 841 } 842 843 func BenchmarkSprintfInt(b *testing.B) { 844 b.RunParallel(func(pb *testing.PB) { 845 for pb.Next() { 846 Sprintf("%d", 5) 847 } 848 }) 849 } 850 851 func BenchmarkSprintfIntInt(b *testing.B) { 852 b.RunParallel(func(pb *testing.PB) { 853 for pb.Next() { 854 Sprintf("%d %d", 5, 6) 855 } 856 }) 857 } 858 859 func BenchmarkSprintfPrefixedInt(b *testing.B) { 860 b.RunParallel(func(pb *testing.PB) { 861 for pb.Next() { 862 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6) 863 } 864 }) 865 } 866 867 func BenchmarkSprintfFloat(b *testing.B) { 868 b.RunParallel(func(pb *testing.PB) { 869 for pb.Next() { 870 Sprintf("%g", 5.23184) 871 } 872 }) 873 } 874 875 func BenchmarkManyArgs(b *testing.B) { 876 b.RunParallel(func(pb *testing.PB) { 877 var buf bytes.Buffer 878 for pb.Next() { 879 buf.Reset() 880 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world") 881 } 882 }) 883 } 884 885 func BenchmarkFprintInt(b *testing.B) { 886 var buf bytes.Buffer 887 for i := 0; i < b.N; i++ { 888 buf.Reset() 889 Fprint(&buf, 123456) 890 } 891 } 892 893 func BenchmarkFprintfBytes(b *testing.B) { 894 data := []byte(string("0123456789")) 895 var buf bytes.Buffer 896 for i := 0; i < b.N; i++ { 897 buf.Reset() 898 Fprintf(&buf, "%s", data) 899 } 900 } 901 902 func BenchmarkFprintIntNoAlloc(b *testing.B) { 903 var x interface{} = 123456 904 var buf bytes.Buffer 905 for i := 0; i < b.N; i++ { 906 buf.Reset() 907 Fprint(&buf, x) 908 } 909 } 910 911 var mallocBuf bytes.Buffer 912 var mallocPointer *int // A pointer so we know the interface value won't allocate. 913 914 var mallocTest = []struct { 915 count int 916 desc string 917 fn func() 918 }{ 919 {0, `Sprintf("")`, func() { Sprintf("") }}, 920 {1, `Sprintf("xxx")`, func() { Sprintf("xxx") }}, 921 {2, `Sprintf("%x")`, func() { Sprintf("%x", 7) }}, 922 {2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }}, 923 {3, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }}, 924 {2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1? 925 {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }}, 926 // If the interface value doesn't need to allocate, amortized allocation overhead should be zero. 927 {0, `Fprintf(buf, "%x %x %x")`, func() { 928 mallocBuf.Reset() 929 Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer) 930 }}, 931 } 932 933 var _ bytes.Buffer 934 935 func TestCountMallocs(t *testing.T) { 936 if testing.Short() { 937 t.Skip("skipping malloc count in short mode") 938 } 939 if runtime.GOMAXPROCS(0) > 1 { 940 t.Skip("skipping; GOMAXPROCS>1") 941 } 942 for _, mt := range mallocTest { 943 mallocs := testing.AllocsPerRun(100, mt.fn) 944 if got, max := mallocs, float64(mt.count); got > max { 945 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max) 946 } 947 } 948 } 949 950 type flagPrinter struct{} 951 952 func (flagPrinter) Format(f State, c rune) { 953 s := "%" 954 for i := 0; i < 128; i++ { 955 if f.Flag(i) { 956 s += string(i) 957 } 958 } 959 if w, ok := f.Width(); ok { 960 s += Sprintf("%d", w) 961 } 962 if p, ok := f.Precision(); ok { 963 s += Sprintf(".%d", p) 964 } 965 s += string(c) 966 io.WriteString(f, "["+s+"]") 967 } 968 969 var flagtests = []struct { 970 in string 971 out string 972 }{ 973 {"%a", "[%a]"}, 974 {"%-a", "[%-a]"}, 975 {"%+a", "[%+a]"}, 976 {"%#a", "[%#a]"}, 977 {"% a", "[% a]"}, 978 {"%0a", "[%0a]"}, 979 {"%1.2a", "[%1.2a]"}, 980 {"%-1.2a", "[%-1.2a]"}, 981 {"%+1.2a", "[%+1.2a]"}, 982 {"%-+1.2a", "[%+-1.2a]"}, 983 {"%-+1.2abc", "[%+-1.2a]bc"}, 984 {"%-1.2abc", "[%-1.2a]bc"}, 985 } 986 987 func TestFlagParser(t *testing.T) { 988 var flagprinter flagPrinter 989 for _, tt := range flagtests { 990 s := Sprintf(tt.in, &flagprinter) 991 if s != tt.out { 992 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out) 993 } 994 } 995 } 996 997 func TestStructPrinter(t *testing.T) { 998 type T struct { 999 a string 1000 b string 1001 c int 1002 } 1003 var s T 1004 s.a = "abc" 1005 s.b = "def" 1006 s.c = 123 1007 var tests = []struct { 1008 fmt string 1009 out string 1010 }{ 1011 {"%v", "{abc def 123}"}, 1012 {"%+v", "{a:abc b:def c:123}"}, 1013 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`}, 1014 } 1015 for _, tt := range tests { 1016 out := Sprintf(tt.fmt, s) 1017 if out != tt.out { 1018 t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out) 1019 } 1020 // The same but with a pointer. 1021 out = Sprintf(tt.fmt, &s) 1022 if out != "&"+tt.out { 1023 t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out) 1024 } 1025 } 1026 } 1027 1028 func TestSlicePrinter(t *testing.T) { 1029 slice := []int{} 1030 s := Sprint(slice) 1031 if s != "[]" { 1032 t.Errorf("empty slice printed as %q not %q", s, "[]") 1033 } 1034 slice = []int{1, 2, 3} 1035 s = Sprint(slice) 1036 if s != "[1 2 3]" { 1037 t.Errorf("slice: got %q expected %q", s, "[1 2 3]") 1038 } 1039 s = Sprint(&slice) 1040 if s != "&[1 2 3]" { 1041 t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]") 1042 } 1043 } 1044 1045 // presentInMap checks map printing using substrings so we don't depend on the 1046 // print order. 1047 func presentInMap(s string, a []string, t *testing.T) { 1048 for i := 0; i < len(a); i++ { 1049 loc := strings.Index(s, a[i]) 1050 if loc < 0 { 1051 t.Errorf("map print: expected to find %q in %q", a[i], s) 1052 } 1053 // make sure the match ends here 1054 loc += len(a[i]) 1055 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') { 1056 t.Errorf("map print: %q not properly terminated in %q", a[i], s) 1057 } 1058 } 1059 } 1060 1061 func TestMapPrinter(t *testing.T) { 1062 m0 := make(map[int]string) 1063 s := Sprint(m0) 1064 if s != "map[]" { 1065 t.Errorf("empty map printed as %q not %q", s, "map[]") 1066 } 1067 m1 := map[int]string{1: "one", 2: "two", 3: "three"} 1068 a := []string{"1:one", "2:two", "3:three"} 1069 presentInMap(Sprintf("%v", m1), a, t) 1070 presentInMap(Sprint(m1), a, t) 1071 // Pointer to map prints the same but with initial &. 1072 if !strings.HasPrefix(Sprint(&m1), "&") { 1073 t.Errorf("no initial & for address of map") 1074 } 1075 presentInMap(Sprintf("%v", &m1), a, t) 1076 presentInMap(Sprint(&m1), a, t) 1077 } 1078 1079 func TestEmptyMap(t *testing.T) { 1080 const emptyMapStr = "map[]" 1081 var m map[string]int 1082 s := Sprint(m) 1083 if s != emptyMapStr { 1084 t.Errorf("nil map printed as %q not %q", s, emptyMapStr) 1085 } 1086 m = make(map[string]int) 1087 s = Sprint(m) 1088 if s != emptyMapStr { 1089 t.Errorf("empty map printed as %q not %q", s, emptyMapStr) 1090 } 1091 } 1092 1093 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the 1094 // right places, that is, between arg pairs in which neither is a string. 1095 func TestBlank(t *testing.T) { 1096 got := Sprint("<", 1, ">:", 1, 2, 3, "!") 1097 expect := "<1>:1 2 3!" 1098 if got != expect { 1099 t.Errorf("got %q expected %q", got, expect) 1100 } 1101 } 1102 1103 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in 1104 // the right places, that is, between all arg pairs. 1105 func TestBlankln(t *testing.T) { 1106 got := Sprintln("<", 1, ">:", 1, 2, 3, "!") 1107 expect := "< 1 >: 1 2 3 !\n" 1108 if got != expect { 1109 t.Errorf("got %q expected %q", got, expect) 1110 } 1111 } 1112 1113 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf. 1114 func TestFormatterPrintln(t *testing.T) { 1115 f := F(1) 1116 expect := "<v=F(1)>\n" 1117 s := Sprint(f, "\n") 1118 if s != expect { 1119 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s) 1120 } 1121 s = Sprintln(f) 1122 if s != expect { 1123 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s) 1124 } 1125 s = Sprintf("%v\n", f) 1126 if s != expect { 1127 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s) 1128 } 1129 } 1130 1131 func args(a ...interface{}) []interface{} { return a } 1132 1133 var startests = []struct { 1134 fmt string 1135 in []interface{} 1136 out string 1137 }{ 1138 {"%*d", args(4, 42), " 42"}, 1139 {"%.*d", args(4, 42), "0042"}, 1140 {"%*.*d", args(8, 4, 42), " 0042"}, 1141 {"%0*d", args(4, 42), "0042"}, 1142 {"%-*d", args(4, 42), "42 "}, 1143 1144 // erroneous 1145 {"%*d", args(nil, 42), "%!(BADWIDTH)42"}, 1146 {"%.*d", args(nil, 42), "%!(BADPREC)42"}, 1147 {"%*d", args(5, "foo"), "%!d(string= foo)"}, 1148 {"%*% %d", args(20, 5), "% 5"}, 1149 {"%*", args(4), "%!(NOVERB)"}, 1150 {"%*d", args(int32(4), 42), "%!(BADWIDTH)42"}, 1151 } 1152 1153 func TestWidthAndPrecision(t *testing.T) { 1154 for _, tt := range startests { 1155 s := Sprintf(tt.fmt, tt.in...) 1156 if s != tt.out { 1157 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) 1158 } 1159 } 1160 } 1161 1162 // Panic is a type that panics in String. 1163 type Panic struct { 1164 message interface{} 1165 } 1166 1167 // Value receiver. 1168 func (p Panic) GoString() string { 1169 panic(p.message) 1170 } 1171 1172 // Value receiver. 1173 func (p Panic) String() string { 1174 panic(p.message) 1175 } 1176 1177 // PanicF is a type that panics in Format. 1178 type PanicF struct { 1179 message interface{} 1180 } 1181 1182 // Value receiver. 1183 func (p PanicF) Format(f State, c rune) { 1184 panic(p.message) 1185 } 1186 1187 var panictests = []struct { 1188 fmt string 1189 in interface{} 1190 out string 1191 }{ 1192 // String 1193 {"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case 1194 {"%s", Panic{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 1195 {"%s", Panic{3}, "%!s(PANIC=3)"}, 1196 // GoString 1197 {"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case 1198 {"%#v", Panic{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"}, 1199 {"%#v", Panic{3}, "%!v(PANIC=3)"}, 1200 // Format 1201 {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case 1202 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 1203 {"%s", PanicF{3}, "%!s(PANIC=3)"}, 1204 } 1205 1206 func TestPanics(t *testing.T) { 1207 for i, tt := range panictests { 1208 s := Sprintf(tt.fmt, tt.in) 1209 if s != tt.out { 1210 t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out) 1211 } 1212 } 1213 } 1214 1215 // recurCount tests that erroneous String routine doesn't cause fatal recursion. 1216 var recurCount = 0 1217 1218 type Recur struct { 1219 i int 1220 failed *bool 1221 } 1222 1223 func (r *Recur) String() string { 1224 if recurCount++; recurCount > 10 { 1225 *r.failed = true 1226 return "FAIL" 1227 } 1228 // This will call badVerb. Before the fix, that would cause us to recur into 1229 // this routine to print %!p(value). Now we don't call the user's method 1230 // during an error. 1231 return Sprintf("recur@%p value: %d", r, r.i) 1232 } 1233 1234 func TestBadVerbRecursion(t *testing.T) { 1235 failed := false 1236 r := &Recur{3, &failed} 1237 Sprintf("recur@%p value: %d\n", &r, r.i) 1238 if failed { 1239 t.Error("fail with pointer") 1240 } 1241 failed = false 1242 r = &Recur{4, &failed} 1243 Sprintf("recur@%p, value: %d\n", r, r.i) 1244 if failed { 1245 t.Error("fail with value") 1246 } 1247 } 1248 1249 func TestIsSpace(t *testing.T) { 1250 // This tests the internal isSpace function. 1251 // IsSpace = isSpace is defined in export_test.go. 1252 for i := rune(0); i <= unicode.MaxRune; i++ { 1253 if IsSpace(i) != unicode.IsSpace(i) { 1254 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i)) 1255 } 1256 } 1257 } 1258 1259 func TestNilDoesNotBecomeTyped(t *testing.T) { 1260 type A struct{} 1261 type B struct{} 1262 var a *A = nil 1263 var b B = B{} 1264 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) // go vet should complain about this line. 1265 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)" 1266 if got != expect { 1267 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) 1268 } 1269 } 1270 1271 var formatterFlagTests = []struct { 1272 in string 1273 val interface{} 1274 out string 1275 }{ 1276 // scalar values with the (unused by fmt) 'a' verb. 1277 {"%a", flagPrinter{}, "[%a]"}, 1278 {"%-a", flagPrinter{}, "[%-a]"}, 1279 {"%+a", flagPrinter{}, "[%+a]"}, 1280 {"%#a", flagPrinter{}, "[%#a]"}, 1281 {"% a", flagPrinter{}, "[% a]"}, 1282 {"%0a", flagPrinter{}, "[%0a]"}, 1283 {"%1.2a", flagPrinter{}, "[%1.2a]"}, 1284 {"%-1.2a", flagPrinter{}, "[%-1.2a]"}, 1285 {"%+1.2a", flagPrinter{}, "[%+1.2a]"}, 1286 {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"}, 1287 {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"}, 1288 {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"}, 1289 1290 // composite values with the 'a' verb 1291 {"%a", [1]flagPrinter{}, "[[%a]]"}, 1292 {"%-a", [1]flagPrinter{}, "[[%-a]]"}, 1293 {"%+a", [1]flagPrinter{}, "[[%+a]]"}, 1294 {"%#a", [1]flagPrinter{}, "[[%#a]]"}, 1295 {"% a", [1]flagPrinter{}, "[[% a]]"}, 1296 {"%0a", [1]flagPrinter{}, "[[%0a]]"}, 1297 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"}, 1298 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"}, 1299 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"}, 1300 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"}, 1301 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"}, 1302 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"}, 1303 1304 // simple values with the 'v' verb 1305 {"%v", flagPrinter{}, "[%v]"}, 1306 {"%-v", flagPrinter{}, "[%-v]"}, 1307 {"%+v", flagPrinter{}, "[%+v]"}, 1308 {"%#v", flagPrinter{}, "[%#v]"}, 1309 {"% v", flagPrinter{}, "[% v]"}, 1310 {"%0v", flagPrinter{}, "[%0v]"}, 1311 {"%1.2v", flagPrinter{}, "[%1.2v]"}, 1312 {"%-1.2v", flagPrinter{}, "[%-1.2v]"}, 1313 {"%+1.2v", flagPrinter{}, "[%+1.2v]"}, 1314 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"}, 1315 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"}, 1316 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"}, 1317 1318 // composite values with the 'v' verb. 1319 {"%v", [1]flagPrinter{}, "[[%v]]"}, 1320 {"%-v", [1]flagPrinter{}, "[[%-v]]"}, 1321 {"%+v", [1]flagPrinter{}, "[[%+v]]"}, 1322 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"}, 1323 {"% v", [1]flagPrinter{}, "[[% v]]"}, 1324 {"%0v", [1]flagPrinter{}, "[[%0v]]"}, 1325 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"}, 1326 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"}, 1327 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"}, 1328 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"}, 1329 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"}, 1330 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"}, 1331 } 1332 1333 func TestFormatterFlags(t *testing.T) { 1334 for _, tt := range formatterFlagTests { 1335 s := Sprintf(tt.in, tt.val) 1336 if s != tt.out { 1337 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out) 1338 } 1339 } 1340 }