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 // Padding with byte slices. 456 {"%x", []byte{}, ""}, 457 {"%02x", []byte{}, "00"}, 458 {"% 02x", []byte{}, "00"}, 459 {"%08x", []byte{0xab}, "000000ab"}, 460 {"% 08x", []byte{0xab}, "000000ab"}, 461 {"%08x", []byte{0xab, 0xcd}, "0000abcd"}, 462 {"% 08x", []byte{0xab, 0xcd}, "000ab cd"}, 463 {"%8x", []byte{0xab}, " ab"}, 464 {"% 8x", []byte{0xab}, " ab"}, 465 {"%8x", []byte{0xab, 0xcd}, " abcd"}, 466 {"% 8x", []byte{0xab, 0xcd}, " ab cd"}, 467 // Same for strings 468 {"%x", "", ""}, 469 {"%02x", "", "00"}, 470 {"% 02x", "", "00"}, 471 {"%08x", "\xab", "000000ab"}, 472 {"% 08x", "\xab", "000000ab"}, 473 {"%08x", "\xab\xcd", "0000abcd"}, 474 {"% 08x", "\xab\xcd", "000ab cd"}, 475 {"%8x", "\xab", " ab"}, 476 {"% 8x", "\xab", " ab"}, 477 {"%8x", "\xab\xcd", " abcd"}, 478 {"% 8x", "\xab\xcd", " ab cd"}, 479 480 // renamings 481 {"%v", renamedBool(true), "true"}, 482 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"}, 483 {"%o", renamedInt(8), "10"}, 484 {"%d", renamedInt8(-9), "-9"}, 485 {"%v", renamedInt16(10), "10"}, 486 {"%v", renamedInt32(-11), "-11"}, 487 {"%X", renamedInt64(255), "FF"}, 488 {"%v", renamedUint(13), "13"}, 489 {"%o", renamedUint8(14), "16"}, 490 {"%X", renamedUint16(15), "F"}, 491 {"%d", renamedUint32(16), "16"}, 492 {"%X", renamedUint64(17), "11"}, 493 {"%o", renamedUintptr(18), "22"}, 494 {"%x", renamedString("thing"), "7468696e67"}, 495 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`}, 496 {"%q", renamedBytes([]byte("hello")), `"hello"`}, 497 {"%x", []renamedUint8{'a', 'b', 'c'}, "616263"}, 498 {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"}, 499 {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`}, 500 {"%v", renamedFloat32(22), "22"}, 501 {"%v", renamedFloat64(33), "33"}, 502 {"%v", renamedComplex64(3 + 4i), "(3+4i)"}, 503 {"%v", renamedComplex128(4 - 3i), "(4-3i)"}, 504 505 // Formatter 506 {"%x", F(1), "<x=F(1)>"}, 507 {"%x", G(2), "2"}, 508 {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"}, 509 510 // GoStringer 511 {"%#v", G(6), "GoString(6)"}, 512 {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"}, 513 514 // %T 515 {"%T", (4 - 3i), "complex128"}, 516 {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"}, 517 {"%T", intVal, "int"}, 518 {"%6T", &intVal, " *int"}, 519 {"%10T", nil, " <nil>"}, 520 {"%-10T", nil, "<nil> "}, 521 522 // %p 523 {"p0=%p", new(int), "p0=0xPTR"}, 524 {"p1=%s", &pValue, "p1=String(p)"}, // String method... 525 {"p2=%p", &pValue, "p2=0xPTR"}, // ... not called with %p 526 {"p3=%p", (*int)(nil), "p3=0x0"}, 527 {"p4=%#p", new(int), "p4=PTR"}, 528 529 // %p on non-pointers 530 {"%p", make(chan int), "0xPTR"}, 531 {"%p", make(map[int]int), "0xPTR"}, 532 {"%p", make([]int, 1), "0xPTR"}, 533 {"%p", 27, "%!p(int=27)"}, // not a pointer at all 534 535 // %q on pointers 536 {"%q", (*int)(nil), "%!q(*int=<nil>)"}, 537 {"%q", new(int), "%!q(*int=0xPTR)"}, 538 539 // %v on pointers formats 0 as <nil> 540 {"%v", (*int)(nil), "<nil>"}, 541 {"%v", new(int), "0xPTR"}, 542 543 // %d etc. pointers use specified base. 544 {"%d", new(int), "PTR_d"}, 545 {"%o", new(int), "PTR_o"}, 546 {"%x", new(int), "PTR_x"}, 547 548 // %d on Stringer should give integer if possible 549 {"%s", time.Time{}.Month(), "January"}, 550 {"%d", time.Time{}.Month(), "1"}, 551 552 // erroneous things 553 {"%s %", "hello", "hello %!(NOVERB)"}, 554 {"%s %.2", "hello", "hello %!(NOVERB)"}, 555 {"%d", "hello", "%!d(string=hello)"}, 556 {"no args", "hello", "no args%!(EXTRA string=hello)"}, 557 {"%s", nil, "%!s(<nil>)"}, 558 {"%T", nil, "<nil>"}, 559 {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"}, 560 {"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)%!(EXTRA int=0)"}, 561 {"%184467440737095516170v", 0, "%!(NOVERB)%!(EXTRA int=0)"}, 562 563 // The "<nil>" show up because maps are printed by 564 // first obtaining a list of keys and then looking up 565 // each key. Since NaNs can be map keys but cannot 566 // be fetched directly, the lookup fails and returns a 567 // zero reflect.Value, which formats as <nil>. 568 // This test is just to check that it shows the two NaNs at all. 569 {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"}, 570 571 // Used to crash because nByte didn't allow for a sign. 572 {"%b", int64(-1 << 63), zeroFill("-1", 63, "")}, 573 574 // Used to panic. 575 {"%0100d", 1, zeroFill("", 100, "1")}, 576 {"%0100d", -1, zeroFill("-", 99, "1")}, 577 {"%0.100f", 1.0, zeroFill("1.", 100, "")}, 578 {"%0.100f", -1.0, zeroFill("-1.", 100, "")}, 579 580 // Used to panic: integer function didn't look at f.prec, f.unicode, f.width or sign. 581 {"%#.80x", 42, "0x0000000000000000000000000000000000000000000000000000000000000000000000000000002a"}, 582 {"%.80U", 42, "U+0000000000000000000000000000000000000000000000000000000000000000000000000000002A"}, 583 {"%#.80U", '', "U+000000000000000000000000000000000000000000000000000000000000000000000000000065E5 ''"}, 584 {"%.65d", -44, "-00000000000000000000000000000000000000000000000000000000000000044"}, 585 {"%+.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"}, 586 {"% .65d", 44, " 00000000000000000000000000000000000000000000000000000000000000044"}, 587 {"% +.65d", 44, "+00000000000000000000000000000000000000000000000000000000000000044"}, 588 589 // Comparison of padding rules with C printf. 590 /* 591 C program: 592 #include <stdio.h> 593 594 char *format[] = { 595 "[%.2f]", 596 "[% .2f]", 597 "[%+.2f]", 598 "[%7.2f]", 599 "[% 7.2f]", 600 "[%+7.2f]", 601 "[%07.2f]", 602 "[% 07.2f]", 603 "[%+07.2f]", 604 }; 605 606 int main(void) { 607 int i; 608 for(i = 0; i < 9; i++) { 609 printf("%s: ", format[i]); 610 printf(format[i], 1.0); 611 printf(" "); 612 printf(format[i], -1.0); 613 printf("\n"); 614 } 615 } 616 617 Output: 618 [%.2f]: [1.00] [-1.00] 619 [% .2f]: [ 1.00] [-1.00] 620 [%+.2f]: [+1.00] [-1.00] 621 [%7.2f]: [ 1.00] [ -1.00] 622 [% 7.2f]: [ 1.00] [ -1.00] 623 [%+7.2f]: [ +1.00] [ -1.00] 624 [%07.2f]: [0001.00] [-001.00] 625 [% 07.2f]: [ 001.00] [-001.00] 626 [%+07.2f]: [+001.00] [-001.00] 627 */ 628 {"%.2f", 1.0, "1.00"}, 629 {"%.2f", -1.0, "-1.00"}, 630 {"% .2f", 1.0, " 1.00"}, 631 {"% .2f", -1.0, "-1.00"}, 632 {"%+.2f", 1.0, "+1.00"}, 633 {"%+.2f", -1.0, "-1.00"}, 634 {"%7.2f", 1.0, " 1.00"}, 635 {"%7.2f", -1.0, " -1.00"}, 636 {"% 7.2f", 1.0, " 1.00"}, 637 {"% 7.2f", -1.0, " -1.00"}, 638 {"%+7.2f", 1.0, " +1.00"}, 639 {"%+7.2f", -1.0, " -1.00"}, 640 {"%07.2f", 1.0, "0001.00"}, 641 {"%07.2f", -1.0, "-001.00"}, 642 {"% 07.2f", 1.0, " 001.00"}, 643 {"% 07.2f", -1.0, "-001.00"}, 644 {"%+07.2f", 1.0, "+001.00"}, 645 {"%+07.2f", -1.0, "-001.00"}, 646 647 // Complex numbers: exhaustively tested in TestComplexFormatting. 648 {"%7.2f", 1 + 2i, "( 1.00 +2.00i)"}, 649 {"%+07.2f", -1 - 2i, "(-001.00-002.00i)"}, 650 // Zero padding does not apply to infinities. 651 {"%020f", math.Inf(-1), " -Inf"}, 652 {"%020f", math.Inf(+1), " +Inf"}, 653 {"% 020f", math.Inf(-1), " -Inf"}, 654 {"% 020f", math.Inf(+1), " Inf"}, 655 {"%+020f", math.Inf(-1), " -Inf"}, 656 {"%+020f", math.Inf(+1), " +Inf"}, 657 {"%20f", -1.0, " -1.000000"}, 658 // Make sure we can handle very large widths. 659 {"%0100f", -1.0, zeroFill("-", 99, "1.000000")}, 660 661 // Complex fmt used to leave the plus flag set for future entries in the array 662 // causing +2+0i and +3+0i instead of 2+0i and 3+0i. 663 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, 664 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, 665 666 // Incomplete format specification caused crash. 667 {"%.", 3, "%!.(int=3)"}, 668 669 // Used to panic with out-of-bounds for very large numeric representations. 670 // nByte is set to handle one bit per uint64 in %b format, with a negative number. 671 // See issue 6777. 672 {"%#064x", 1, zeroFill("0x", 64, "1")}, 673 {"%#064x", -1, zeroFill("-0x", 63, "1")}, 674 {"%#064b", 1, zeroFill("", 64, "1")}, 675 {"%#064b", -1, zeroFill("-", 63, "1")}, 676 {"%#064o", 1, zeroFill("", 64, "1")}, 677 {"%#064o", -1, zeroFill("-", 63, "1")}, 678 {"%#064d", 1, zeroFill("", 64, "1")}, 679 {"%#064d", -1, zeroFill("-", 63, "1")}, 680 // Test that we handle the crossover above the size of uint64 681 {"%#072x", 1, zeroFill("0x", 72, "1")}, 682 {"%#072x", -1, zeroFill("-0x", 71, "1")}, 683 {"%#072b", 1, zeroFill("", 72, "1")}, 684 {"%#072b", -1, zeroFill("-", 71, "1")}, 685 {"%#072o", 1, zeroFill("", 72, "1")}, 686 {"%#072o", -1, zeroFill("-", 71, "1")}, 687 {"%#072d", 1, zeroFill("", 72, "1")}, 688 {"%#072d", -1, zeroFill("-", 71, "1")}, 689 690 // Padding for complex numbers. Has been bad, then fixed, then bad again. 691 {"%+10.2f", +104.66 + 440.51i, "( +104.66 +440.51i)"}, 692 {"%+10.2f", -104.66 + 440.51i, "( -104.66 +440.51i)"}, 693 {"%+10.2f", +104.66 - 440.51i, "( +104.66 -440.51i)"}, 694 {"%+10.2f", -104.66 - 440.51i, "( -104.66 -440.51i)"}, 695 {"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"}, 696 {"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"}, 697 {"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"}, 698 {"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"}, 699 700 // []T where type T is a byte with a Stringer method. 701 {"%v", byteStringerSlice, "[X X X X]"}, 702 {"%s", byteStringerSlice, "abcd"}, 703 {"%q", byteStringerSlice, "\"abcd\""}, 704 {"%x", byteStringerSlice, "61626364"}, 705 {"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x61, 0x62, 0x63, 0x64}"}, 706 707 // And the same for Formatter. 708 {"%v", byteFormatterSlice, "[X X X X]"}, 709 {"%s", byteFormatterSlice, "abcd"}, 710 {"%q", byteFormatterSlice, "\"abcd\""}, 711 {"%x", byteFormatterSlice, "61626364"}, 712 // This next case seems wrong, but the docs say the Formatter wins here. 713 {"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X}"}, 714 715 // reflect.Value handled specially in Go 1.5, making it possible to 716 // see inside non-exported fields (which cannot be accessed with Interface()). 717 // Issue 8965. 718 {"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"}, // Equivalent to the old way. 719 {"%v", reflect.ValueOf(A{}).Field(0), "0"}, // Sees inside the field. 720 721 // verbs apply to the extracted value too. 722 {"%s", reflect.ValueOf("hello"), "hello"}, 723 {"%q", reflect.ValueOf("hello"), `"hello"`}, 724 {"%#04x", reflect.ValueOf(256), "0x0100"}, 725 726 // invalid reflect.Value doesn't crash. 727 {"%v", reflect.Value{}, "<invalid reflect.Value>"}, 728 } 729 730 // zeroFill generates zero-filled strings of the specified width. The length 731 // of the suffix (but not the prefix) is compensated for in the width calculation. 732 func zeroFill(prefix string, width int, suffix string) string { 733 return prefix + strings.Repeat("0", width-len(suffix)) + suffix 734 } 735 736 func TestSprintf(t *testing.T) { 737 for _, tt := range fmtTests { 738 s := Sprintf(tt.fmt, tt.val) 739 if i := strings.Index(tt.out, "PTR"); i >= 0 { 740 pattern := "PTR" 741 chars := "0123456789abcdefABCDEF" 742 switch { 743 case strings.HasPrefix(tt.out[i:], "PTR_d"): 744 pattern = "PTR_d" 745 chars = chars[:10] 746 case strings.HasPrefix(tt.out[i:], "PTR_o"): 747 pattern = "PTR_o" 748 chars = chars[:8] 749 case strings.HasPrefix(tt.out[i:], "PTR_x"): 750 pattern = "PTR_x" 751 } 752 j := i 753 for ; j < len(s); j++ { 754 c := s[j] 755 if !strings.ContainsRune(chars, rune(c)) { 756 break 757 } 758 } 759 s = s[0:i] + pattern + s[j:] 760 } 761 if s != tt.out { 762 if _, ok := tt.val.(string); ok { 763 // Don't requote the already-quoted strings. 764 // It's too confusing to read the errors. 765 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out) 766 } else { 767 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out) 768 } 769 } 770 } 771 } 772 773 // TestComplexFormatting checks that a complex always formats to the same 774 // thing as if done by hand with two singleton prints. 775 func TestComplexFormatting(t *testing.T) { 776 var yesNo = []bool{true, false} 777 var values = []float64{1, 0, -1, math.Inf(1), math.Inf(-1), math.NaN()} 778 for _, plus := range yesNo { 779 for _, zero := range yesNo { 780 for _, space := range yesNo { 781 for _, char := range "fFeEgG" { 782 realFmt := "%" 783 if zero { 784 realFmt += "0" 785 } 786 if space { 787 realFmt += " " 788 } 789 if plus { 790 realFmt += "+" 791 } 792 realFmt += "10.2" 793 realFmt += string(char) 794 // Imaginary part always has a sign, so force + and ignore space. 795 imagFmt := "%" 796 if zero { 797 imagFmt += "0" 798 } 799 imagFmt += "+" 800 imagFmt += "10.2" 801 imagFmt += string(char) 802 for _, realValue := range values { 803 for _, imagValue := range values { 804 one := Sprintf(realFmt, complex(realValue, imagValue)) 805 two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue) 806 if one != two { 807 t.Error(f, one, two) 808 } 809 } 810 } 811 } 812 } 813 } 814 } 815 } 816 817 type SE []interface{} // slice of empty; notational compactness. 818 819 var reorderTests = []struct { 820 fmt string 821 val SE 822 out string 823 }{ 824 {"%[1]d", SE{1}, "1"}, 825 {"%[2]d", SE{2, 1}, "1"}, 826 {"%[2]d %[1]d", SE{1, 2}, "2 1"}, 827 {"%[2]*[1]d", SE{2, 5}, " 2"}, 828 {"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line. 829 {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"}, 830 {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"}, 831 {"%10f", SE{12.0}, " 12.000000"}, 832 {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"}, 833 {"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line. 834 {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"}, 835 {"%6.f", SE{12.0}, " 12"}, // // Explicit version of next line; empty precision means zero. 836 {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"}, 837 // An actual use! Print the same arguments twice. 838 {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"}, 839 840 // Erroneous cases. 841 {"%[d", SE{2, 1}, "%!d(BADINDEX)"}, 842 {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"}, 843 {"%[]d", SE{2, 1}, "%!d(BADINDEX)"}, 844 {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"}, 845 {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"}, 846 {"%[3]", SE{2, 1}, "%!(NOVERB)"}, 847 {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"}, 848 {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"}, 849 {"%3.[2]d", SE{7}, "%!d(BADINDEX)"}, 850 {"%.[2]d", SE{7}, "%!d(BADINDEX)"}, 851 {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"}, 852 {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"}, 853 {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence. 854 {"%.[]", SE{}, "%!](BADINDEX)"}, // Issue 10675 855 {"%.-3d", SE{42}, "%!-(int=42)3d"}, // TODO: Should this set return better error messages? 856 {"%2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"}, 857 {"%-2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"}, 858 {"%.2147483648d", SE{42}, "%!(NOVERB)%!(EXTRA int=42)"}, 859 } 860 861 func TestReorder(t *testing.T) { 862 for _, tt := range reorderTests { 863 s := Sprintf(tt.fmt, tt.val...) 864 if s != tt.out { 865 t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out) 866 } else { 867 } 868 } 869 } 870 871 func BenchmarkSprintfEmpty(b *testing.B) { 872 b.RunParallel(func(pb *testing.PB) { 873 for pb.Next() { 874 Sprintf("") 875 } 876 }) 877 } 878 879 func BenchmarkSprintfString(b *testing.B) { 880 b.RunParallel(func(pb *testing.PB) { 881 for pb.Next() { 882 Sprintf("%s", "hello") 883 } 884 }) 885 } 886 887 func BenchmarkSprintfInt(b *testing.B) { 888 b.RunParallel(func(pb *testing.PB) { 889 for pb.Next() { 890 Sprintf("%d", 5) 891 } 892 }) 893 } 894 895 func BenchmarkSprintfIntInt(b *testing.B) { 896 b.RunParallel(func(pb *testing.PB) { 897 for pb.Next() { 898 Sprintf("%d %d", 5, 6) 899 } 900 }) 901 } 902 903 func BenchmarkSprintfPrefixedInt(b *testing.B) { 904 b.RunParallel(func(pb *testing.PB) { 905 for pb.Next() { 906 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6) 907 } 908 }) 909 } 910 911 func BenchmarkSprintfFloat(b *testing.B) { 912 b.RunParallel(func(pb *testing.PB) { 913 for pb.Next() { 914 Sprintf("%g", 5.23184) 915 } 916 }) 917 } 918 919 func BenchmarkManyArgs(b *testing.B) { 920 b.RunParallel(func(pb *testing.PB) { 921 var buf bytes.Buffer 922 for pb.Next() { 923 buf.Reset() 924 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world") 925 } 926 }) 927 } 928 929 func BenchmarkFprintInt(b *testing.B) { 930 var buf bytes.Buffer 931 for i := 0; i < b.N; i++ { 932 buf.Reset() 933 Fprint(&buf, 123456) 934 } 935 } 936 937 func BenchmarkFprintfBytes(b *testing.B) { 938 data := []byte(string("0123456789")) 939 var buf bytes.Buffer 940 for i := 0; i < b.N; i++ { 941 buf.Reset() 942 Fprintf(&buf, "%s", data) 943 } 944 } 945 946 func BenchmarkFprintIntNoAlloc(b *testing.B) { 947 var x interface{} = 123456 948 var buf bytes.Buffer 949 for i := 0; i < b.N; i++ { 950 buf.Reset() 951 Fprint(&buf, x) 952 } 953 } 954 955 var mallocBuf bytes.Buffer 956 var mallocPointer *int // A pointer so we know the interface value won't allocate. 957 958 var mallocTest = []struct { 959 count int 960 desc string 961 fn func() 962 }{ 963 {0, `Sprintf("")`, func() { Sprintf("") }}, 964 {1, `Sprintf("xxx")`, func() { Sprintf("xxx") }}, 965 {2, `Sprintf("%x")`, func() { Sprintf("%x", 7) }}, 966 {2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }}, 967 {3, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }}, 968 {2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1? 969 {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }}, 970 // If the interface value doesn't need to allocate, amortized allocation overhead should be zero. 971 {0, `Fprintf(buf, "%x %x %x")`, func() { 972 mallocBuf.Reset() 973 Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer) 974 }}, 975 } 976 977 var _ bytes.Buffer 978 979 func TestCountMallocs(t *testing.T) { 980 switch { 981 case testing.Short(): 982 t.Skip("skipping malloc count in short mode") 983 case runtime.GOMAXPROCS(0) > 1: 984 t.Skip("skipping; GOMAXPROCS>1") 985 case raceenabled: 986 t.Skip("skipping malloc count under race detector") 987 } 988 for _, mt := range mallocTest { 989 mallocs := testing.AllocsPerRun(100, mt.fn) 990 if got, max := mallocs, float64(mt.count); got > max { 991 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max) 992 } 993 } 994 } 995 996 type flagPrinter struct{} 997 998 func (flagPrinter) Format(f State, c rune) { 999 s := "%" 1000 for i := 0; i < 128; i++ { 1001 if f.Flag(i) { 1002 s += string(i) 1003 } 1004 } 1005 if w, ok := f.Width(); ok { 1006 s += Sprintf("%d", w) 1007 } 1008 if p, ok := f.Precision(); ok { 1009 s += Sprintf(".%d", p) 1010 } 1011 s += string(c) 1012 io.WriteString(f, "["+s+"]") 1013 } 1014 1015 var flagtests = []struct { 1016 in string 1017 out string 1018 }{ 1019 {"%a", "[%a]"}, 1020 {"%-a", "[%-a]"}, 1021 {"%+a", "[%+a]"}, 1022 {"%#a", "[%#a]"}, 1023 {"% a", "[% a]"}, 1024 {"%0a", "[%0a]"}, 1025 {"%1.2a", "[%1.2a]"}, 1026 {"%-1.2a", "[%-1.2a]"}, 1027 {"%+1.2a", "[%+1.2a]"}, 1028 {"%-+1.2a", "[%+-1.2a]"}, 1029 {"%-+1.2abc", "[%+-1.2a]bc"}, 1030 {"%-1.2abc", "[%-1.2a]bc"}, 1031 } 1032 1033 func TestFlagParser(t *testing.T) { 1034 var flagprinter flagPrinter 1035 for _, tt := range flagtests { 1036 s := Sprintf(tt.in, &flagprinter) 1037 if s != tt.out { 1038 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out) 1039 } 1040 } 1041 } 1042 1043 func TestStructPrinter(t *testing.T) { 1044 type T struct { 1045 a string 1046 b string 1047 c int 1048 } 1049 var s T 1050 s.a = "abc" 1051 s.b = "def" 1052 s.c = 123 1053 var tests = []struct { 1054 fmt string 1055 out string 1056 }{ 1057 {"%v", "{abc def 123}"}, 1058 {"%+v", "{a:abc b:def c:123}"}, 1059 {"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`}, 1060 } 1061 for _, tt := range tests { 1062 out := Sprintf(tt.fmt, s) 1063 if out != tt.out { 1064 t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out) 1065 } 1066 // The same but with a pointer. 1067 out = Sprintf(tt.fmt, &s) 1068 if out != "&"+tt.out { 1069 t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out) 1070 } 1071 } 1072 } 1073 1074 func TestSlicePrinter(t *testing.T) { 1075 slice := []int{} 1076 s := Sprint(slice) 1077 if s != "[]" { 1078 t.Errorf("empty slice printed as %q not %q", s, "[]") 1079 } 1080 slice = []int{1, 2, 3} 1081 s = Sprint(slice) 1082 if s != "[1 2 3]" { 1083 t.Errorf("slice: got %q expected %q", s, "[1 2 3]") 1084 } 1085 s = Sprint(&slice) 1086 if s != "&[1 2 3]" { 1087 t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]") 1088 } 1089 } 1090 1091 // presentInMap checks map printing using substrings so we don't depend on the 1092 // print order. 1093 func presentInMap(s string, a []string, t *testing.T) { 1094 for i := 0; i < len(a); i++ { 1095 loc := strings.Index(s, a[i]) 1096 if loc < 0 { 1097 t.Errorf("map print: expected to find %q in %q", a[i], s) 1098 } 1099 // make sure the match ends here 1100 loc += len(a[i]) 1101 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') { 1102 t.Errorf("map print: %q not properly terminated in %q", a[i], s) 1103 } 1104 } 1105 } 1106 1107 func TestMapPrinter(t *testing.T) { 1108 m0 := make(map[int]string) 1109 s := Sprint(m0) 1110 if s != "map[]" { 1111 t.Errorf("empty map printed as %q not %q", s, "map[]") 1112 } 1113 m1 := map[int]string{1: "one", 2: "two", 3: "three"} 1114 a := []string{"1:one", "2:two", "3:three"} 1115 presentInMap(Sprintf("%v", m1), a, t) 1116 presentInMap(Sprint(m1), a, t) 1117 // Pointer to map prints the same but with initial &. 1118 if !strings.HasPrefix(Sprint(&m1), "&") { 1119 t.Errorf("no initial & for address of map") 1120 } 1121 presentInMap(Sprintf("%v", &m1), a, t) 1122 presentInMap(Sprint(&m1), a, t) 1123 } 1124 1125 func TestEmptyMap(t *testing.T) { 1126 const emptyMapStr = "map[]" 1127 var m map[string]int 1128 s := Sprint(m) 1129 if s != emptyMapStr { 1130 t.Errorf("nil map printed as %q not %q", s, emptyMapStr) 1131 } 1132 m = make(map[string]int) 1133 s = Sprint(m) 1134 if s != emptyMapStr { 1135 t.Errorf("empty map printed as %q not %q", s, emptyMapStr) 1136 } 1137 } 1138 1139 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the 1140 // right places, that is, between arg pairs in which neither is a string. 1141 func TestBlank(t *testing.T) { 1142 got := Sprint("<", 1, ">:", 1, 2, 3, "!") 1143 expect := "<1>:1 2 3!" 1144 if got != expect { 1145 t.Errorf("got %q expected %q", got, expect) 1146 } 1147 } 1148 1149 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in 1150 // the right places, that is, between all arg pairs. 1151 func TestBlankln(t *testing.T) { 1152 got := Sprintln("<", 1, ">:", 1, 2, 3, "!") 1153 expect := "< 1 >: 1 2 3 !\n" 1154 if got != expect { 1155 t.Errorf("got %q expected %q", got, expect) 1156 } 1157 } 1158 1159 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf. 1160 func TestFormatterPrintln(t *testing.T) { 1161 f := F(1) 1162 expect := "<v=F(1)>\n" 1163 s := Sprint(f, "\n") 1164 if s != expect { 1165 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s) 1166 } 1167 s = Sprintln(f) 1168 if s != expect { 1169 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s) 1170 } 1171 s = Sprintf("%v\n", f) 1172 if s != expect { 1173 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s) 1174 } 1175 } 1176 1177 func args(a ...interface{}) []interface{} { return a } 1178 1179 var startests = []struct { 1180 fmt string 1181 in []interface{} 1182 out string 1183 }{ 1184 {"%*d", args(4, 42), " 42"}, 1185 {"%-*d", args(4, 42), "42 "}, 1186 {"%*d", args(-4, 42), "42 "}, 1187 {"%-*d", args(-4, 42), "42 "}, 1188 {"%.*d", args(4, 42), "0042"}, 1189 {"%*.*d", args(8, 4, 42), " 0042"}, 1190 {"%0*d", args(4, 42), "0042"}, 1191 1192 // erroneous 1193 {"%*d", args(nil, 42), "%!(BADWIDTH)42"}, 1194 {"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"}, 1195 {"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"}, 1196 {"%.*d", args(nil, 42), "%!(BADPREC)42"}, 1197 {"%.*d", args(-1, 42), "%!(BADPREC)42"}, 1198 {"%.*d", args(int(1e7), 42), "%!(BADPREC)42"}, 1199 {"%*d", args(5, "foo"), "%!d(string= foo)"}, 1200 {"%*% %d", args(20, 5), "% 5"}, 1201 {"%*", args(4), "%!(NOVERB)"}, 1202 {"%*d", args(int32(4), 42), "%!(BADWIDTH)42"}, 1203 } 1204 1205 func TestWidthAndPrecision(t *testing.T) { 1206 for _, tt := range startests { 1207 s := Sprintf(tt.fmt, tt.in...) 1208 if s != tt.out { 1209 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) 1210 } 1211 } 1212 } 1213 1214 // Panic is a type that panics in String. 1215 type Panic struct { 1216 message interface{} 1217 } 1218 1219 // Value receiver. 1220 func (p Panic) GoString() string { 1221 panic(p.message) 1222 } 1223 1224 // Value receiver. 1225 func (p Panic) String() string { 1226 panic(p.message) 1227 } 1228 1229 // PanicF is a type that panics in Format. 1230 type PanicF struct { 1231 message interface{} 1232 } 1233 1234 // Value receiver. 1235 func (p PanicF) Format(f State, c rune) { 1236 panic(p.message) 1237 } 1238 1239 var panictests = []struct { 1240 fmt string 1241 in interface{} 1242 out string 1243 }{ 1244 // String 1245 {"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case 1246 {"%s", Panic{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 1247 {"%s", Panic{3}, "%!s(PANIC=3)"}, 1248 // GoString 1249 {"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case 1250 {"%#v", Panic{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"}, 1251 {"%#v", Panic{3}, "%!v(PANIC=3)"}, 1252 // Format 1253 {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case 1254 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 1255 {"%s", PanicF{3}, "%!s(PANIC=3)"}, 1256 } 1257 1258 func TestPanics(t *testing.T) { 1259 for i, tt := range panictests { 1260 s := Sprintf(tt.fmt, tt.in) 1261 if s != tt.out { 1262 t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out) 1263 } 1264 } 1265 } 1266 1267 // recurCount tests that erroneous String routine doesn't cause fatal recursion. 1268 var recurCount = 0 1269 1270 type Recur struct { 1271 i int 1272 failed *bool 1273 } 1274 1275 func (r *Recur) String() string { 1276 if recurCount++; recurCount > 10 { 1277 *r.failed = true 1278 return "FAIL" 1279 } 1280 // This will call badVerb. Before the fix, that would cause us to recur into 1281 // this routine to print %!p(value). Now we don't call the user's method 1282 // during an error. 1283 return Sprintf("recur@%p value: %d", r, r.i) 1284 } 1285 1286 func TestBadVerbRecursion(t *testing.T) { 1287 failed := false 1288 r := &Recur{3, &failed} 1289 Sprintf("recur@%p value: %d\n", &r, r.i) 1290 if failed { 1291 t.Error("fail with pointer") 1292 } 1293 failed = false 1294 r = &Recur{4, &failed} 1295 Sprintf("recur@%p, value: %d\n", r, r.i) 1296 if failed { 1297 t.Error("fail with value") 1298 } 1299 } 1300 1301 func TestIsSpace(t *testing.T) { 1302 // This tests the internal isSpace function. 1303 // IsSpace = isSpace is defined in export_test.go. 1304 for i := rune(0); i <= unicode.MaxRune; i++ { 1305 if IsSpace(i) != unicode.IsSpace(i) { 1306 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i)) 1307 } 1308 } 1309 } 1310 1311 func TestNilDoesNotBecomeTyped(t *testing.T) { 1312 type A struct{} 1313 type B struct{} 1314 var a *A = nil 1315 var b B = B{} 1316 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) // go vet should complain about this line. 1317 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)" 1318 if got != expect { 1319 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) 1320 } 1321 } 1322 1323 var formatterFlagTests = []struct { 1324 in string 1325 val interface{} 1326 out string 1327 }{ 1328 // scalar values with the (unused by fmt) 'a' verb. 1329 {"%a", flagPrinter{}, "[%a]"}, 1330 {"%-a", flagPrinter{}, "[%-a]"}, 1331 {"%+a", flagPrinter{}, "[%+a]"}, 1332 {"%#a", flagPrinter{}, "[%#a]"}, 1333 {"% a", flagPrinter{}, "[% a]"}, 1334 {"%0a", flagPrinter{}, "[%0a]"}, 1335 {"%1.2a", flagPrinter{}, "[%1.2a]"}, 1336 {"%-1.2a", flagPrinter{}, "[%-1.2a]"}, 1337 {"%+1.2a", flagPrinter{}, "[%+1.2a]"}, 1338 {"%-+1.2a", flagPrinter{}, "[%+-1.2a]"}, 1339 {"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"}, 1340 {"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"}, 1341 1342 // composite values with the 'a' verb 1343 {"%a", [1]flagPrinter{}, "[[%a]]"}, 1344 {"%-a", [1]flagPrinter{}, "[[%-a]]"}, 1345 {"%+a", [1]flagPrinter{}, "[[%+a]]"}, 1346 {"%#a", [1]flagPrinter{}, "[[%#a]]"}, 1347 {"% a", [1]flagPrinter{}, "[[% a]]"}, 1348 {"%0a", [1]flagPrinter{}, "[[%0a]]"}, 1349 {"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"}, 1350 {"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"}, 1351 {"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"}, 1352 {"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"}, 1353 {"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"}, 1354 {"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"}, 1355 1356 // simple values with the 'v' verb 1357 {"%v", flagPrinter{}, "[%v]"}, 1358 {"%-v", flagPrinter{}, "[%-v]"}, 1359 {"%+v", flagPrinter{}, "[%+v]"}, 1360 {"%#v", flagPrinter{}, "[%#v]"}, 1361 {"% v", flagPrinter{}, "[% v]"}, 1362 {"%0v", flagPrinter{}, "[%0v]"}, 1363 {"%1.2v", flagPrinter{}, "[%1.2v]"}, 1364 {"%-1.2v", flagPrinter{}, "[%-1.2v]"}, 1365 {"%+1.2v", flagPrinter{}, "[%+1.2v]"}, 1366 {"%-+1.2v", flagPrinter{}, "[%+-1.2v]"}, 1367 {"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"}, 1368 {"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"}, 1369 1370 // composite values with the 'v' verb. 1371 {"%v", [1]flagPrinter{}, "[[%v]]"}, 1372 {"%-v", [1]flagPrinter{}, "[[%-v]]"}, 1373 {"%+v", [1]flagPrinter{}, "[[%+v]]"}, 1374 {"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"}, 1375 {"% v", [1]flagPrinter{}, "[[% v]]"}, 1376 {"%0v", [1]flagPrinter{}, "[[%0v]]"}, 1377 {"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"}, 1378 {"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"}, 1379 {"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"}, 1380 {"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"}, 1381 {"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"}, 1382 {"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"}, 1383 } 1384 1385 func TestFormatterFlags(t *testing.T) { 1386 for _, tt := range formatterFlagTests { 1387 s := Sprintf(tt.in, tt.val) 1388 if s != tt.out { 1389 t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out) 1390 } 1391 } 1392 } 1393