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