github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/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 var b byte 112 113 var fmtTests = []struct { 114 fmt string 115 val interface{} 116 out string 117 }{ 118 {"%d", 12345, "12345"}, 119 {"%v", 12345, "12345"}, 120 {"%t", true, "true"}, 121 122 // basic string 123 {"%s", "abc", "abc"}, 124 {"%x", "abc", "616263"}, 125 {"%x", "xyz", "78797a"}, 126 {"%X", "xyz", "78797A"}, 127 {"%q", "abc", `"abc"`}, 128 129 // basic bytes 130 {"%s", []byte("abc"), "abc"}, 131 {"%x", []byte("abc"), "616263"}, 132 {"% x", []byte("abc\xff"), "61 62 63 ff"}, 133 {"%#x", []byte("abc\xff"), "0x610x620x630xff"}, 134 {"%#X", []byte("abc\xff"), "0X610X620X630XFF"}, 135 {"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"}, 136 {"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"}, 137 {"% X", []byte("abc\xff"), "61 62 63 FF"}, 138 {"%x", []byte("xyz"), "78797a"}, 139 {"%X", []byte("xyz"), "78797A"}, 140 {"%q", []byte("abc"), `"abc"`}, 141 142 // escaped strings 143 {"%#q", `abc`, "`abc`"}, 144 {"%#q", `"`, "`\"`"}, 145 {"1 %#q", `\n`, "1 `\\n`"}, 146 {"2 %#q", "\n", `2 "\n"`}, 147 {"%q", `"`, `"\""`}, 148 {"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`}, 149 {"%q", "abc\xffdef", `"abc\xffdef"`}, 150 {"%q", "\u263a", `"☺"`}, 151 {"%+q", "\u263a", `"\u263a"`}, 152 {"%q", "\U0010ffff", `"\U0010ffff"`}, 153 154 // escaped characters 155 {"%q", 'x', `'x'`}, 156 {"%q", 0, `'\x00'`}, 157 {"%q", '\n', `'\n'`}, 158 {"%q", '\u0e00', `'\u0e00'`}, // not a printable rune. 159 {"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune. 160 {"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`}, 161 {"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`}, 162 {"%q", '"', `'"'`}, 163 {"%q", '\'', `'\''`}, 164 {"%q", "\u263a", `"☺"`}, 165 {"%+q", "\u263a", `"\u263a"`}, 166 167 // width 168 {"%5s", "abc", " abc"}, 169 {"%2s", "\u263a", " ☺"}, 170 {"%-5s", "abc", "abc "}, 171 {"%-8q", "abc", `"abc" `}, 172 {"%05s", "abc", "00abc"}, 173 {"%08q", "abc", `000"abc"`}, 174 {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"}, 175 {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"}, 176 {"%.5s", "日本語日本語", "日本語日本"}, 177 {"%.5s", []byte("日本語日本語"), "日本語日本"}, 178 {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`}, 179 {"%.3q", "日本語日本語", `"日本語"`}, 180 {"%.3q", []byte("日本語日本語"), `"日本語"`}, 181 {"%10.1q", "日本語日本語", ` "日"`}, 182 {"%10v", nil, " <nil>"}, 183 {"%-10v", nil, "<nil> "}, 184 185 // integers 186 {"%d", 12345, "12345"}, 187 {"%d", -12345, "-12345"}, 188 {"%10d", 12345, " 12345"}, 189 {"%10d", -12345, " -12345"}, 190 {"%+10d", 12345, " +12345"}, 191 {"%010d", 12345, "0000012345"}, 192 {"%010d", -12345, "-000012345"}, 193 {"%-10d", 12345, "12345 "}, 194 {"%010.3d", 1, " 001"}, 195 {"%010.3d", -1, " -001"}, 196 {"%+d", 12345, "+12345"}, 197 {"%+d", -12345, "-12345"}, 198 {"%+d", 0, "+0"}, 199 {"% d", 0, " 0"}, 200 {"% d", 12345, " 12345"}, 201 {"%.0d", 0, ""}, 202 {"%.d", 0, ""}, 203 204 // unicode format 205 {"%U", 0x1, "U+0001"}, 206 {"%U", uint(0x1), "U+0001"}, 207 {"%.8U", 0x2, "U+00000002"}, 208 {"%U", 0x1234, "U+1234"}, 209 {"%U", 0x12345, "U+12345"}, 210 {"%10.6U", 0xABC, " U+000ABC"}, 211 {"%-10.6U", 0xABC, "U+000ABC "}, 212 {"%U", '\n', `U+000A`}, 213 {"%#U", '\n', `U+000A`}, 214 {"%U", 'x', `U+0078`}, 215 {"%#U", 'x', `U+0078 'x'`}, 216 {"%U", '\u263a', `U+263A`}, 217 {"%#U", '\u263a', `U+263A '☺'`}, 218 219 // floats 220 {"%+.3e", 0.0, "+0.000e+00"}, 221 {"%+.3e", 1.0, "+1.000e+00"}, 222 {"%+.3f", -1.0, "-1.000"}, 223 {"% .3E", -1.0, "-1.000E+00"}, 224 {"% .3e", 1.0, " 1.000e+00"}, 225 {"%+.3g", 0.0, "+0"}, 226 {"%+.3g", 1.0, "+1"}, 227 {"%+.3g", -1.0, "-1"}, 228 {"% .3g", -1.0, "-1"}, 229 {"% .3g", 1.0, " 1"}, 230 {"%b", float32(1.0), "8388608p-23"}, 231 {"%b", 1.0, "4503599627370496p-52"}, 232 233 // complex values 234 {"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"}, 235 {"%+.3f", 0i, "(+0.000+0.000i)"}, 236 {"%+.3g", 0i, "(+0+0i)"}, 237 {"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"}, 238 {"%+.3f", 1 + 2i, "(+1.000+2.000i)"}, 239 {"%+.3g", 1 + 2i, "(+1+2i)"}, 240 {"%.3e", 0i, "(0.000e+00+0.000e+00i)"}, 241 {"%.3f", 0i, "(0.000+0.000i)"}, 242 {"%.3g", 0i, "(0+0i)"}, 243 {"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"}, 244 {"%.3f", 1 + 2i, "(1.000+2.000i)"}, 245 {"%.3g", 1 + 2i, "(1+2i)"}, 246 {"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"}, 247 {"%.3f", -1 - 2i, "(-1.000-2.000i)"}, 248 {"%.3g", -1 - 2i, "(-1-2i)"}, 249 {"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"}, 250 {"%+.3g", complex64(1 + 2i), "(+1+2i)"}, 251 {"%+.3g", complex128(1 + 2i), "(+1+2i)"}, 252 {"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"}, 253 {"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"}, 254 255 // erroneous formats 256 {"", 2, "%!(EXTRA int=2)"}, 257 {"%d", "hello", "%!d(string=hello)"}, 258 259 // old test/fmt_test.go 260 {"%d", 1234, "1234"}, 261 {"%d", -1234, "-1234"}, 262 {"%d", uint(1234), "1234"}, 263 {"%d", uint32(b32), "4294967295"}, 264 {"%d", uint64(b64), "18446744073709551615"}, 265 {"%o", 01234, "1234"}, 266 {"%#o", 01234, "01234"}, 267 {"%o", uint32(b32), "37777777777"}, 268 {"%o", uint64(b64), "1777777777777777777777"}, 269 {"%x", 0x1234abcd, "1234abcd"}, 270 {"%#x", 0x1234abcd, "0x1234abcd"}, 271 {"%x", b32 - 0x1234567, "fedcba98"}, 272 {"%X", 0x1234abcd, "1234ABCD"}, 273 {"%X", b32 - 0x1234567, "FEDCBA98"}, 274 {"%#X", 0, "0X0"}, 275 {"%x", b64, "ffffffffffffffff"}, 276 {"%b", 7, "111"}, 277 {"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"}, 278 {"%b", -6, "-110"}, 279 {"%e", 1.0, "1.000000e+00"}, 280 {"%e", 1234.5678e3, "1.234568e+06"}, 281 {"%e", 1234.5678e-8, "1.234568e-05"}, 282 {"%e", -7.0, "-7.000000e+00"}, 283 {"%e", -1e-9, "-1.000000e-09"}, 284 {"%f", 1234.5678e3, "1234567.800000"}, 285 {"%f", 1234.5678e-8, "0.000012"}, 286 {"%f", -7.0, "-7.000000"}, 287 {"%f", -1e-9, "-0.000000"}, 288 {"%g", 1234.5678e3, "1.2345678e+06"}, 289 {"%g", float32(1234.5678e3), "1.2345678e+06"}, 290 {"%g", 1234.5678e-8, "1.2345678e-05"}, 291 {"%g", -7.0, "-7"}, 292 {"%g", -1e-9, "-1e-09"}, 293 {"%g", float32(-1e-9), "-1e-09"}, 294 {"%E", 1.0, "1.000000E+00"}, 295 {"%E", 1234.5678e3, "1.234568E+06"}, 296 {"%E", 1234.5678e-8, "1.234568E-05"}, 297 {"%E", -7.0, "-7.000000E+00"}, 298 {"%E", -1e-9, "-1.000000E-09"}, 299 {"%G", 1234.5678e3, "1.2345678E+06"}, 300 {"%G", float32(1234.5678e3), "1.2345678E+06"}, 301 {"%G", 1234.5678e-8, "1.2345678E-05"}, 302 {"%G", -7.0, "-7"}, 303 {"%G", -1e-9, "-1E-09"}, 304 {"%G", float32(-1e-9), "-1E-09"}, 305 {"%c", 'x', "x"}, 306 {"%c", 0xe4, "ä"}, 307 {"%c", 0x672c, "本"}, 308 {"%c", '日', "日"}, 309 {"%20.8d", 1234, " 00001234"}, 310 {"%20.8d", -1234, " -00001234"}, 311 {"%20d", 1234, " 1234"}, 312 {"%-20.8d", 1234, "00001234 "}, 313 {"%-20.8d", -1234, "-00001234 "}, 314 {"%-#20.8x", 0x1234abc, "0x01234abc "}, 315 {"%-#20.8X", 0x1234abc, "0X01234ABC "}, 316 {"%-#20.8o", 01234, "00001234 "}, 317 {"%.20b", 7, "00000000000000000111"}, 318 {"%20.5s", "qwertyuiop", " qwert"}, 319 {"%.5s", "qwertyuiop", "qwert"}, 320 {"%-20.5s", "qwertyuiop", "qwert "}, 321 {"%20c", 'x', " x"}, 322 {"%-20c", 'x', "x "}, 323 {"%20.6e", 1.2345e3, " 1.234500e+03"}, 324 {"%20.6e", 1.2345e-3, " 1.234500e-03"}, 325 {"%20e", 1.2345e3, " 1.234500e+03"}, 326 {"%20e", 1.2345e-3, " 1.234500e-03"}, 327 {"%20.8e", 1.2345e3, " 1.23450000e+03"}, 328 {"%20f", 1.23456789e3, " 1234.567890"}, 329 {"%20f", 1.23456789e-3, " 0.001235"}, 330 {"%20f", 12345678901.23456789, " 12345678901.234568"}, 331 {"%-20f", 1.23456789e3, "1234.567890 "}, 332 {"%20.8f", 1.23456789e3, " 1234.56789000"}, 333 {"%20.8f", 1.23456789e-3, " 0.00123457"}, 334 {"%g", 1.23456789e3, "1234.56789"}, 335 {"%g", 1.23456789e-3, "0.00123456789"}, 336 {"%g", 1.23456789e20, "1.23456789e+20"}, 337 {"%20e", math.Inf(1), " +Inf"}, 338 {"%-20f", math.Inf(-1), "-Inf "}, 339 {"%20g", math.NaN(), " NaN"}, 340 341 // arrays 342 {"%v", array, "[1 2 3 4 5]"}, 343 {"%v", iarray, "[1 hello 2.5 <nil>]"}, 344 {"%v", barray, "[1 2 3 4 5]"}, 345 {"%v", &array, "&[1 2 3 4 5]"}, 346 {"%v", &iarray, "&[1 hello 2.5 <nil>]"}, 347 {"%v", &barray, "&[1 2 3 4 5]"}, 348 349 // slices 350 {"%v", slice, "[1 2 3 4 5]"}, 351 {"%v", islice, "[1 hello 2.5 <nil>]"}, 352 {"%v", bslice, "[1 2 3 4 5]"}, 353 {"%v", &slice, "&[1 2 3 4 5]"}, 354 {"%v", &islice, "&[1 hello 2.5 <nil>]"}, 355 {"%v", &bslice, "&[1 2 3 4 5]"}, 356 357 // complexes with %v 358 {"%v", 1 + 2i, "(1+2i)"}, 359 {"%v", complex64(1 + 2i), "(1+2i)"}, 360 {"%v", complex128(1 + 2i), "(1+2i)"}, 361 362 // structs 363 {"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`}, 364 {"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`}, 365 366 // +v on structs with Stringable items 367 {"%+v", B{1, 2}, `{I:<1> j:2}`}, 368 {"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`}, 369 370 // other formats on Stringable items 371 {"%s", I(23), `<23>`}, 372 {"%q", I(23), `"<23>"`}, 373 {"%x", I(23), `3c32333e`}, 374 {"%#x", I(23), `0x3c0x320x330x3e`}, 375 {"%# x", I(23), `0x3c 0x32 0x33 0x3e`}, 376 {"%d", I(23), `23`}, // Stringer applies only to string formats. 377 378 // go syntax 379 {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`}, 380 {"%#v", &b, "(*uint8)(0xPTR)"}, 381 {"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"}, 382 {"%#v", make(chan int), "(chan int)(0xPTR)"}, 383 {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"}, 384 {"%#v", 1000000000, "1000000000"}, 385 {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`}, 386 {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`}, 387 {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`}, 388 {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`}, 389 {"%#v", []int(nil), `[]int(nil)`}, 390 {"%#v", []int{}, `[]int{}`}, 391 {"%#v", array, `[5]int{1, 2, 3, 4, 5}`}, 392 {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`}, 393 {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`}, 394 {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`}, 395 {"%#v", map[int]byte(nil), `map[int]uint8(nil)`}, 396 {"%#v", map[int]byte{}, `map[int]uint8{}`}, 397 {"%#v", "foo", `"foo"`}, 398 {"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`}, 399 {"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`}, 400 401 // slices with other formats 402 {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`}, 403 {"%x", []int{1, 2, 15}, `[1 2 f]`}, 404 {"%d", []int{1, 2, 15}, `[1 2 15]`}, 405 {"%d", []byte{1, 2, 15}, `[1 2 15]`}, 406 {"%q", []string{"a", "b"}, `["a" "b"]`}, 407 408 // renamings 409 {"%v", renamedBool(true), "true"}, 410 {"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"}, 411 {"%o", renamedInt(8), "10"}, 412 {"%d", renamedInt8(-9), "-9"}, 413 {"%v", renamedInt16(10), "10"}, 414 {"%v", renamedInt32(-11), "-11"}, 415 {"%X", renamedInt64(255), "FF"}, 416 {"%v", renamedUint(13), "13"}, 417 {"%o", renamedUint8(14), "16"}, 418 {"%X", renamedUint16(15), "F"}, 419 {"%d", renamedUint32(16), "16"}, 420 {"%X", renamedUint64(17), "11"}, 421 {"%o", renamedUintptr(18), "22"}, 422 {"%x", renamedString("thing"), "7468696e67"}, 423 {"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`}, 424 {"%q", renamedBytes([]byte("hello")), `"hello"`}, 425 {"%x", []renamedUint8{'a', 'b', 'c'}, "616263"}, 426 {"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"}, 427 {"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`}, 428 {"%v", renamedFloat32(22), "22"}, 429 {"%v", renamedFloat64(33), "33"}, 430 {"%v", renamedComplex64(3 + 4i), "(3+4i)"}, 431 {"%v", renamedComplex128(4 - 3i), "(4-3i)"}, 432 433 // Formatter 434 {"%x", F(1), "<x=F(1)>"}, 435 {"%x", G(2), "2"}, 436 {"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"}, 437 438 // GoStringer 439 {"%#v", G(6), "GoString(6)"}, 440 {"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"}, 441 442 // %T 443 {"%T", (4 - 3i), "complex128"}, 444 {"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"}, 445 {"%T", intVal, "int"}, 446 {"%6T", &intVal, " *int"}, 447 {"%10T", nil, " <nil>"}, 448 {"%-10T", nil, "<nil> "}, 449 450 // %p 451 {"p0=%p", new(int), "p0=0xPTR"}, 452 {"p1=%s", &pValue, "p1=String(p)"}, // String method... 453 {"p2=%p", &pValue, "p2=0xPTR"}, // ... not called with %p 454 {"p3=%p", (*int)(nil), "p3=0x0"}, 455 {"p4=%#p", new(int), "p4=PTR"}, 456 457 // %p on non-pointers 458 {"%p", make(chan int), "0xPTR"}, 459 {"%p", make(map[int]int), "0xPTR"}, 460 {"%p", make([]int, 1), "0xPTR"}, 461 {"%p", 27, "%!p(int=27)"}, // not a pointer at all 462 463 // %q on pointers 464 {"%q", (*int)(nil), "%!q(*int=<nil>)"}, 465 {"%q", new(int), "%!q(*int=0xPTR)"}, 466 467 // %v on pointers formats 0 as <nil> 468 {"%v", (*int)(nil), "<nil>"}, 469 {"%v", new(int), "0xPTR"}, 470 471 // %d etc. pointers use specified base. 472 {"%d", new(int), "PTR_d"}, 473 {"%o", new(int), "PTR_o"}, 474 {"%x", new(int), "PTR_x"}, 475 476 // %d on Stringer should give integer if possible 477 {"%s", time.Time{}.Month(), "January"}, 478 {"%d", time.Time{}.Month(), "1"}, 479 480 // erroneous things 481 {"%s %", "hello", "hello %!(NOVERB)"}, 482 {"%s %.2", "hello", "hello %!(NOVERB)"}, 483 {"%d", "hello", "%!d(string=hello)"}, 484 {"no args", "hello", "no args%!(EXTRA string=hello)"}, 485 {"%s", nil, "%!s(<nil>)"}, 486 {"%T", nil, "<nil>"}, 487 {"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"}, 488 489 // The "<nil>" show up because maps are printed by 490 // first obtaining a list of keys and then looking up 491 // each key. Since NaNs can be map keys but cannot 492 // be fetched directly, the lookup fails and returns a 493 // zero reflect.Value, which formats as <nil>. 494 // This test is just to check that it shows the two NaNs at all. 495 {"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"}, 496 497 // Used to crash because nByte didn't allow for a sign. 498 {"%b", int64(-1 << 63), "-1000000000000000000000000000000000000000000000000000000000000000"}, 499 500 // Used to panic. 501 {"%0100d", 1, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"}, 502 {"%0100d", -1, "-000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"}, 503 {"%0.100f", 1.0, "1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, 504 {"%0.100f", -1.0, "-1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, 505 506 // Zero padding floats used to put the minus sign in the middle. 507 {"%020f", -1.0, "-000000000001.000000"}, 508 {"%20f", -1.0, " -1.000000"}, 509 {"%0100f", -1.0, "-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.000000"}, 510 511 // Complex fmt used to leave the plus flag set for future entries in the array 512 // causing +2+0i and +3+0i instead of 2+0i and 3+0i. 513 {"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, 514 {"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"}, 515 516 // Incomplete format specification caused crash. 517 {"%.", 3, "%!.(int=3)"}, 518 } 519 520 func TestSprintf(t *testing.T) { 521 for _, tt := range fmtTests { 522 s := Sprintf(tt.fmt, tt.val) 523 if i := strings.Index(tt.out, "PTR"); i >= 0 { 524 pattern := "PTR" 525 chars := "0123456789abcdefABCDEF" 526 switch { 527 case strings.HasPrefix(tt.out[i:], "PTR_d"): 528 pattern = "PTR_d" 529 chars = chars[:10] 530 case strings.HasPrefix(tt.out[i:], "PTR_o"): 531 pattern = "PTR_o" 532 chars = chars[:8] 533 case strings.HasPrefix(tt.out[i:], "PTR_x"): 534 pattern = "PTR_x" 535 } 536 j := i 537 for ; j < len(s); j++ { 538 c := s[j] 539 if !strings.ContainsRune(chars, rune(c)) { 540 break 541 } 542 } 543 s = s[0:i] + pattern + s[j:] 544 } 545 if s != tt.out { 546 if _, ok := tt.val.(string); ok { 547 // Don't requote the already-quoted strings. 548 // It's too confusing to read the errors. 549 t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out) 550 } else { 551 t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out) 552 } 553 } 554 } 555 } 556 557 type SE []interface{} // slice of empty; notational compactness. 558 559 var reorderTests = []struct { 560 fmt string 561 val SE 562 out string 563 }{ 564 {"%[1]d", SE{1}, "1"}, 565 {"%[2]d", SE{2, 1}, "1"}, 566 {"%[2]d %[1]d", SE{1, 2}, "2 1"}, 567 {"%[2]*[1]d", SE{2, 5}, " 2"}, 568 {"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line. 569 {"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"}, 570 {"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"}, 571 {"%10f", SE{12.0}, " 12.000000"}, 572 {"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"}, 573 {"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line. 574 {"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"}, 575 {"%6.f", SE{12.0}, " 12"}, // // Explicit version of next line; empty precision means zero. 576 {"%[1]*.[3]f", SE{6, 3, 12.0}, " 12"}, 577 // An actual use! Print the same arguments twice. 578 {"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"}, 579 580 // Erroneous cases. 581 {"%[d", SE{2, 1}, "%!d(BADINDEX)"}, 582 {"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"}, 583 {"%[]d", SE{2, 1}, "%!d(BADINDEX)"}, 584 {"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"}, 585 {"%[99]d", SE{2, 1}, "%!d(BADINDEX)"}, 586 {"%[3]", SE{2, 1}, "%!(NOVERB)"}, 587 {"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"}, 588 {"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"}, 589 {"%3.[2]d", SE{7}, "%!d(BADINDEX)"}, 590 {"%.[2]d", SE{7}, "%!d(BADINDEX)"}, 591 {"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"}, 592 {"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"}, 593 {"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence. 594 } 595 596 func TestReorder(t *testing.T) { 597 for _, tt := range reorderTests { 598 s := Sprintf(tt.fmt, tt.val...) 599 if s != tt.out { 600 t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out) 601 } else { 602 } 603 } 604 } 605 606 func BenchmarkSprintfEmpty(b *testing.B) { 607 for i := 0; i < b.N; i++ { 608 Sprintf("") 609 } 610 } 611 612 func BenchmarkSprintfString(b *testing.B) { 613 for i := 0; i < b.N; i++ { 614 Sprintf("%s", "hello") 615 } 616 } 617 618 func BenchmarkSprintfInt(b *testing.B) { 619 for i := 0; i < b.N; i++ { 620 Sprintf("%d", 5) 621 } 622 } 623 624 func BenchmarkSprintfIntInt(b *testing.B) { 625 for i := 0; i < b.N; i++ { 626 Sprintf("%d %d", 5, 6) 627 } 628 } 629 630 func BenchmarkSprintfPrefixedInt(b *testing.B) { 631 for i := 0; i < b.N; i++ { 632 Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6) 633 } 634 } 635 636 func BenchmarkSprintfFloat(b *testing.B) { 637 for i := 0; i < b.N; i++ { 638 Sprintf("%g", 5.23184) 639 } 640 } 641 642 func BenchmarkManyArgs(b *testing.B) { 643 var buf bytes.Buffer 644 for i := 0; i < b.N; i++ { 645 buf.Reset() 646 Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world") 647 } 648 } 649 650 var mallocBuf bytes.Buffer 651 652 var mallocTest = []struct { 653 count int 654 desc string 655 fn func() 656 }{ 657 {0, `Sprintf("")`, func() { Sprintf("") }}, 658 {1, `Sprintf("xxx")`, func() { Sprintf("xxx") }}, 659 {1, `Sprintf("%x")`, func() { Sprintf("%x", 7) }}, 660 {2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }}, 661 {1, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }}, 662 // For %g we use a float32, not float64, to guarantee passing the argument 663 // does not need to allocate memory to store the result in a pointer-sized word. 664 {2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, 665 {0, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }}, 666 {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }}, 667 } 668 669 var _ bytes.Buffer 670 671 func TestCountMallocs(t *testing.T) { 672 if testing.Short() { 673 t.Skip("skipping malloc count in short mode") 674 } 675 if runtime.GOMAXPROCS(0) > 1 { 676 t.Skip("skipping; GOMAXPROCS>1") 677 } 678 for _, mt := range mallocTest { 679 mallocs := testing.AllocsPerRun(100, mt.fn) 680 if got, max := mallocs, float64(mt.count); got > max { 681 t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max) 682 } 683 } 684 } 685 686 type flagPrinter struct{} 687 688 func (*flagPrinter) Format(f State, c rune) { 689 s := "%" 690 for i := 0; i < 128; i++ { 691 if f.Flag(i) { 692 s += string(i) 693 } 694 } 695 if w, ok := f.Width(); ok { 696 s += Sprintf("%d", w) 697 } 698 if p, ok := f.Precision(); ok { 699 s += Sprintf(".%d", p) 700 } 701 s += string(c) 702 io.WriteString(f, "["+s+"]") 703 } 704 705 var flagtests = []struct { 706 in string 707 out string 708 }{ 709 {"%a", "[%a]"}, 710 {"%-a", "[%-a]"}, 711 {"%+a", "[%+a]"}, 712 {"%#a", "[%#a]"}, 713 {"% a", "[% a]"}, 714 {"%0a", "[%0a]"}, 715 {"%1.2a", "[%1.2a]"}, 716 {"%-1.2a", "[%-1.2a]"}, 717 {"%+1.2a", "[%+1.2a]"}, 718 {"%-+1.2a", "[%+-1.2a]"}, 719 {"%-+1.2abc", "[%+-1.2a]bc"}, 720 {"%-1.2abc", "[%-1.2a]bc"}, 721 } 722 723 func TestFlagParser(t *testing.T) { 724 var flagprinter flagPrinter 725 for _, tt := range flagtests { 726 s := Sprintf(tt.in, &flagprinter) 727 if s != tt.out { 728 t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out) 729 } 730 } 731 } 732 733 func TestStructPrinter(t *testing.T) { 734 var s struct { 735 a string 736 b string 737 c int 738 } 739 s.a = "abc" 740 s.b = "def" 741 s.c = 123 742 var tests = []struct { 743 fmt string 744 out string 745 }{ 746 {"%v", "{abc def 123}"}, 747 {"%+v", "{a:abc b:def c:123}"}, 748 } 749 for _, tt := range tests { 750 out := Sprintf(tt.fmt, s) 751 if out != tt.out { 752 t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out) 753 } 754 } 755 } 756 757 // presentInMap checks map printing using substrings so we don't depend on the 758 // print order. 759 func presentInMap(s string, a []string, t *testing.T) { 760 for i := 0; i < len(a); i++ { 761 loc := strings.Index(s, a[i]) 762 if loc < 0 { 763 t.Errorf("map print: expected to find %q in %q", a[i], s) 764 } 765 // make sure the match ends here 766 loc += len(a[i]) 767 if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') { 768 t.Errorf("map print: %q not properly terminated in %q", a[i], s) 769 } 770 } 771 } 772 773 func TestMapPrinter(t *testing.T) { 774 m0 := make(map[int]string) 775 s := Sprint(m0) 776 if s != "map[]" { 777 t.Errorf("empty map printed as %q not %q", s, "map[]") 778 } 779 m1 := map[int]string{1: "one", 2: "two", 3: "three"} 780 a := []string{"1:one", "2:two", "3:three"} 781 presentInMap(Sprintf("%v", m1), a, t) 782 presentInMap(Sprint(m1), a, t) 783 } 784 785 func TestEmptyMap(t *testing.T) { 786 const emptyMapStr = "map[]" 787 var m map[string]int 788 s := Sprint(m) 789 if s != emptyMapStr { 790 t.Errorf("nil map printed as %q not %q", s, emptyMapStr) 791 } 792 m = make(map[string]int) 793 s = Sprint(m) 794 if s != emptyMapStr { 795 t.Errorf("empty map printed as %q not %q", s, emptyMapStr) 796 } 797 } 798 799 // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the 800 // right places, that is, between arg pairs in which neither is a string. 801 func TestBlank(t *testing.T) { 802 got := Sprint("<", 1, ">:", 1, 2, 3, "!") 803 expect := "<1>:1 2 3!" 804 if got != expect { 805 t.Errorf("got %q expected %q", got, expect) 806 } 807 } 808 809 // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in 810 // the right places, that is, between all arg pairs. 811 func TestBlankln(t *testing.T) { 812 got := Sprintln("<", 1, ">:", 1, 2, 3, "!") 813 expect := "< 1 >: 1 2 3 !\n" 814 if got != expect { 815 t.Errorf("got %q expected %q", got, expect) 816 } 817 } 818 819 // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf. 820 func TestFormatterPrintln(t *testing.T) { 821 f := F(1) 822 expect := "<v=F(1)>\n" 823 s := Sprint(f, "\n") 824 if s != expect { 825 t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s) 826 } 827 s = Sprintln(f) 828 if s != expect { 829 t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s) 830 } 831 s = Sprintf("%v\n", f) 832 if s != expect { 833 t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s) 834 } 835 } 836 837 func args(a ...interface{}) []interface{} { return a } 838 839 var startests = []struct { 840 fmt string 841 in []interface{} 842 out string 843 }{ 844 {"%*d", args(4, 42), " 42"}, 845 {"%.*d", args(4, 42), "0042"}, 846 {"%*.*d", args(8, 4, 42), " 0042"}, 847 {"%0*d", args(4, 42), "0042"}, 848 {"%-*d", args(4, 42), "42 "}, 849 850 // erroneous 851 {"%*d", args(nil, 42), "%!(BADWIDTH)42"}, 852 {"%.*d", args(nil, 42), "%!(BADPREC)42"}, 853 {"%*d", args(5, "foo"), "%!d(string= foo)"}, 854 {"%*% %d", args(20, 5), "% 5"}, 855 {"%*", args(4), "%!(NOVERB)"}, 856 {"%*d", args(int32(4), 42), "%!(BADWIDTH)42"}, 857 } 858 859 func TestWidthAndPrecision(t *testing.T) { 860 for _, tt := range startests { 861 s := Sprintf(tt.fmt, tt.in...) 862 if s != tt.out { 863 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) 864 } 865 } 866 } 867 868 // Panic is a type that panics in String. 869 type Panic struct { 870 message interface{} 871 } 872 873 // Value receiver. 874 func (p Panic) GoString() string { 875 panic(p.message) 876 } 877 878 // Value receiver. 879 func (p Panic) String() string { 880 panic(p.message) 881 } 882 883 // PanicF is a type that panics in Format. 884 type PanicF struct { 885 message interface{} 886 } 887 888 // Value receiver. 889 func (p PanicF) Format(f State, c rune) { 890 panic(p.message) 891 } 892 893 var panictests = []struct { 894 fmt string 895 in interface{} 896 out string 897 }{ 898 // String 899 {"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case 900 {"%s", Panic{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 901 {"%s", Panic{3}, "%!s(PANIC=3)"}, 902 // GoString 903 {"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case 904 {"%#v", Panic{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"}, 905 {"%#v", Panic{3}, "%!v(PANIC=3)"}, 906 // Format 907 {"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case 908 {"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"}, 909 {"%s", PanicF{3}, "%!s(PANIC=3)"}, 910 } 911 912 func TestPanics(t *testing.T) { 913 for _, tt := range panictests { 914 s := Sprintf(tt.fmt, tt.in) 915 if s != tt.out { 916 t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out) 917 } 918 } 919 } 920 921 // recurCount tests that erroneous String routine doesn't cause fatal recursion. 922 var recurCount = 0 923 924 type Recur struct { 925 i int 926 failed *bool 927 } 928 929 func (r *Recur) String() string { 930 if recurCount++; recurCount > 10 { 931 *r.failed = true 932 return "FAIL" 933 } 934 // This will call badVerb. Before the fix, that would cause us to recur into 935 // this routine to print %!p(value). Now we don't call the user's method 936 // during an error. 937 return Sprintf("recur@%p value: %d", r, r.i) 938 } 939 940 func TestBadVerbRecursion(t *testing.T) { 941 failed := false 942 r := &Recur{3, &failed} 943 Sprintf("recur@%p value: %d\n", &r, r.i) 944 if failed { 945 t.Error("fail with pointer") 946 } 947 failed = false 948 r = &Recur{4, &failed} 949 Sprintf("recur@%p, value: %d\n", r, r.i) 950 if failed { 951 t.Error("fail with value") 952 } 953 } 954 955 func TestIsSpace(t *testing.T) { 956 // This tests the internal isSpace function. 957 // IsSpace = isSpace is defined in export_test.go. 958 for i := rune(0); i <= unicode.MaxRune; i++ { 959 if IsSpace(i) != unicode.IsSpace(i) { 960 t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i)) 961 } 962 } 963 } 964 965 func TestNilDoesNotBecomeTyped(t *testing.T) { 966 type A struct{} 967 type B struct{} 968 var a *A = nil 969 var b B = B{} 970 got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil) 971 const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)" 972 if got != expect { 973 t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got) 974 } 975 }