...
Run Format

Source file src/pkg/fmt/fmt_test.go

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

View as plain text