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