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		{"% .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		// Complex fmt used to leave the plus flag set for future entries in the array
   497		// causing +2+0i and +3+0i instead of 2+0i and 3+0i.
   498		{"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
   499		{"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
   500	
   501		// Incomplete format specification caused crash.
   502		{"%.", 3, "%!.(int=3)"},
   503	}
   504	
   505	func TestSprintf(t *testing.T) {
   506		for _, tt := range fmttests {
   507			s := Sprintf(tt.fmt, tt.val)
   508			if i := strings.Index(tt.out, "PTR"); i >= 0 {
   509				pattern := "PTR"
   510				chars := "0123456789abcdefABCDEF"
   511				switch {
   512				case strings.HasPrefix(tt.out[i:], "PTR_d"):
   513					pattern = "PTR_d"
   514					chars = chars[:10]
   515				case strings.HasPrefix(tt.out[i:], "PTR_o"):
   516					pattern = "PTR_o"
   517					chars = chars[:8]
   518				case strings.HasPrefix(tt.out[i:], "PTR_x"):
   519					pattern = "PTR_x"
   520				}
   521				j := i
   522				for ; j < len(s); j++ {
   523					c := s[j]
   524					if !strings.ContainsRune(chars, rune(c)) {
   525						break
   526					}
   527				}
   528				s = s[0:i] + pattern + s[j:]
   529			}
   530			if s != tt.out {
   531				if _, ok := tt.val.(string); ok {
   532					// Don't requote the already-quoted strings.
   533					// It's too confusing to read the errors.
   534					t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
   535				} else {
   536					t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
   537				}
   538			}
   539		}
   540	}
   541	
   542	func BenchmarkSprintfEmpty(b *testing.B) {
   543		for i := 0; i < b.N; i++ {
   544			Sprintf("")
   545		}
   546	}
   547	
   548	func BenchmarkSprintfString(b *testing.B) {
   549		for i := 0; i < b.N; i++ {
   550			Sprintf("%s", "hello")
   551		}
   552	}
   553	
   554	func BenchmarkSprintfInt(b *testing.B) {
   555		for i := 0; i < b.N; i++ {
   556			Sprintf("%d", 5)
   557		}
   558	}
   559	
   560	func BenchmarkSprintfIntInt(b *testing.B) {
   561		for i := 0; i < b.N; i++ {
   562			Sprintf("%d %d", 5, 6)
   563		}
   564	}
   565	
   566	func BenchmarkSprintfPrefixedInt(b *testing.B) {
   567		for i := 0; i < b.N; i++ {
   568			Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
   569		}
   570	}
   571	
   572	func BenchmarkSprintfFloat(b *testing.B) {
   573		for i := 0; i < b.N; i++ {
   574			Sprintf("%g", 5.23184)
   575		}
   576	}
   577	
   578	func BenchmarkManyArgs(b *testing.B) {
   579		var buf bytes.Buffer
   580		for i := 0; i < b.N; i++ {
   581			buf.Reset()
   582			Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
   583		}
   584	}
   585	
   586	var mallocBuf bytes.Buffer
   587	
   588	var mallocTest = []struct {
   589		count int
   590		desc  string
   591		fn    func()
   592	}{
   593		{0, `Sprintf("")`, func() { Sprintf("") }},
   594		{1, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
   595		{1, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
   596		{2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
   597		{1, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
   598		// For %g we use a float32, not float64, to guarantee passing the argument
   599		// does not need to allocate memory to store the result in a pointer-sized word.
   600		{2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }},
   601		{0, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }},
   602		{1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
   603	}
   604	
   605	var _ bytes.Buffer
   606	
   607	func TestCountMallocs(t *testing.T) {
   608		if runtime.GOMAXPROCS(0) > 1 {
   609			t.Skip("skipping; GOMAXPROCS>1")
   610		}
   611		for _, mt := range mallocTest {
   612			mallocs := testing.AllocsPerRun(100, mt.fn)
   613			if got, max := mallocs, float64(mt.count); got > max {
   614				t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
   615			}
   616		}
   617	}
   618	
   619	type flagPrinter struct{}
   620	
   621	func (*flagPrinter) Format(f State, c rune) {
   622		s := "%"
   623		for i := 0; i < 128; i++ {
   624			if f.Flag(i) {
   625				s += string(i)
   626			}
   627		}
   628		if w, ok := f.Width(); ok {
   629			s += Sprintf("%d", w)
   630		}
   631		if p, ok := f.Precision(); ok {
   632			s += Sprintf(".%d", p)
   633		}
   634		s += string(c)
   635		io.WriteString(f, "["+s+"]")
   636	}
   637	
   638	var flagtests = []struct {
   639		in  string
   640		out string
   641	}{
   642		{"%a", "[%a]"},
   643		{"%-a", "[%-a]"},
   644		{"%+a", "[%+a]"},
   645		{"%#a", "[%#a]"},
   646		{"% a", "[% a]"},
   647		{"%0a", "[%0a]"},
   648		{"%1.2a", "[%1.2a]"},
   649		{"%-1.2a", "[%-1.2a]"},
   650		{"%+1.2a", "[%+1.2a]"},
   651		{"%-+1.2a", "[%+-1.2a]"},
   652		{"%-+1.2abc", "[%+-1.2a]bc"},
   653		{"%-1.2abc", "[%-1.2a]bc"},
   654	}
   655	
   656	func TestFlagParser(t *testing.T) {
   657		var flagprinter flagPrinter
   658		for _, tt := range flagtests {
   659			s := Sprintf(tt.in, &flagprinter)
   660			if s != tt.out {
   661				t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
   662			}
   663		}
   664	}
   665	
   666	func TestStructPrinter(t *testing.T) {
   667		var s struct {
   668			a string
   669			b string
   670			c int
   671		}
   672		s.a = "abc"
   673		s.b = "def"
   674		s.c = 123
   675		var tests = []struct {
   676			fmt string
   677			out string
   678		}{
   679			{"%v", "{abc def 123}"},
   680			{"%+v", "{a:abc b:def c:123}"},
   681		}
   682		for _, tt := range tests {
   683			out := Sprintf(tt.fmt, s)
   684			if out != tt.out {
   685				t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out)
   686			}
   687		}
   688	}
   689	
   690	// presentInMap checks map printing using substrings so we don't depend on the
   691	// print order.
   692	func presentInMap(s string, a []string, t *testing.T) {
   693		for i := 0; i < len(a); i++ {
   694			loc := strings.Index(s, a[i])
   695			if loc < 0 {
   696				t.Errorf("map print: expected to find %q in %q", a[i], s)
   697			}
   698			// make sure the match ends here
   699			loc += len(a[i])
   700			if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
   701				t.Errorf("map print: %q not properly terminated in %q", a[i], s)
   702			}
   703		}
   704	}
   705	
   706	func TestMapPrinter(t *testing.T) {
   707		m0 := make(map[int]string)
   708		s := Sprint(m0)
   709		if s != "map[]" {
   710			t.Errorf("empty map printed as %q not %q", s, "map[]")
   711		}
   712		m1 := map[int]string{1: "one", 2: "two", 3: "three"}
   713		a := []string{"1:one", "2:two", "3:three"}
   714		presentInMap(Sprintf("%v", m1), a, t)
   715		presentInMap(Sprint(m1), a, t)
   716	}
   717	
   718	func TestEmptyMap(t *testing.T) {
   719		const emptyMapStr = "map[]"
   720		var m map[string]int
   721		s := Sprint(m)
   722		if s != emptyMapStr {
   723			t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
   724		}
   725		m = make(map[string]int)
   726		s = Sprint(m)
   727		if s != emptyMapStr {
   728			t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
   729		}
   730	}
   731	
   732	// TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
   733	// right places, that is, between arg pairs in which neither is a string.
   734	func TestBlank(t *testing.T) {
   735		got := Sprint("<", 1, ">:", 1, 2, 3, "!")
   736		expect := "<1>:1 2 3!"
   737		if got != expect {
   738			t.Errorf("got %q expected %q", got, expect)
   739		}
   740	}
   741	
   742	// TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
   743	// the right places, that is, between all arg pairs.
   744	func TestBlankln(t *testing.T) {
   745		got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
   746		expect := "< 1 >: 1 2 3 !\n"
   747		if got != expect {
   748			t.Errorf("got %q expected %q", got, expect)
   749		}
   750	}
   751	
   752	// TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
   753	func TestFormatterPrintln(t *testing.T) {
   754		f := F(1)
   755		expect := "<v=F(1)>\n"
   756		s := Sprint(f, "\n")
   757		if s != expect {
   758			t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
   759		}
   760		s = Sprintln(f)
   761		if s != expect {
   762			t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
   763		}
   764		s = Sprintf("%v\n", f)
   765		if s != expect {
   766			t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
   767		}
   768	}
   769	
   770	func args(a ...interface{}) []interface{} { return a }
   771	
   772	var startests = []struct {
   773		fmt string
   774		in  []interface{}
   775		out string
   776	}{
   777		{"%*d", args(4, 42), "  42"},
   778		{"%.*d", args(4, 42), "0042"},
   779		{"%*.*d", args(8, 4, 42), "    0042"},
   780		{"%0*d", args(4, 42), "0042"},
   781		{"%-*d", args(4, 42), "42  "},
   782	
   783		// erroneous
   784		{"%*d", args(nil, 42), "%!(BADWIDTH)42"},
   785		{"%.*d", args(nil, 42), "%!(BADPREC)42"},
   786		{"%*d", args(5, "foo"), "%!d(string=  foo)"},
   787		{"%*% %d", args(20, 5), "% 5"},
   788		{"%*", args(4), "%!(NOVERB)"},
   789		{"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
   790	}
   791	
   792	func TestWidthAndPrecision(t *testing.T) {
   793		for _, tt := range startests {
   794			s := Sprintf(tt.fmt, tt.in...)
   795			if s != tt.out {
   796				t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
   797			}
   798		}
   799	}
   800	
   801	// Panic is a type that panics in String.
   802	type Panic struct {
   803		message interface{}
   804	}
   805	
   806	// Value receiver.
   807	func (p Panic) GoString() string {
   808		panic(p.message)
   809	}
   810	
   811	// Value receiver.
   812	func (p Panic) String() string {
   813		panic(p.message)
   814	}
   815	
   816	// PanicF is a type that panics in Format.
   817	type PanicF struct {
   818		message interface{}
   819	}
   820	
   821	// Value receiver.
   822	func (p PanicF) Format(f State, c rune) {
   823		panic(p.message)
   824	}
   825	
   826	var panictests = []struct {
   827		fmt string
   828		in  interface{}
   829		out string
   830	}{
   831		// String
   832		{"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case
   833		{"%s", Panic{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"},
   834		{"%s", Panic{3}, "%s(PANIC=3)"},
   835		// GoString
   836		{"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case
   837		{"%#v", Panic{io.ErrUnexpectedEOF}, "%v(PANIC=unexpected EOF)"},
   838		{"%#v", Panic{3}, "%v(PANIC=3)"},
   839		// Format
   840		{"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
   841		{"%s", PanicF{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"},
   842		{"%s", PanicF{3}, "%s(PANIC=3)"},
   843	}
   844	
   845	func TestPanics(t *testing.T) {
   846		for _, tt := range panictests {
   847			s := Sprintf(tt.fmt, tt.in)
   848			if s != tt.out {
   849				t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
   850			}
   851		}
   852	}
   853	
   854	// recurCount tests that erroneous String routine doesn't cause fatal recursion.
   855	var recurCount = 0
   856	
   857	type Recur struct {
   858		i      int
   859		failed *bool
   860	}
   861	
   862	func (r Recur) String() string {
   863		if recurCount++; recurCount > 10 {
   864			*r.failed = true
   865			return "FAIL"
   866		}
   867		// This will call badVerb. Before the fix, that would cause us to recur into
   868		// this routine to print %!p(value). Now we don't call the user's method
   869		// during an error.
   870		return Sprintf("recur@%p value: %d", r, r.i)
   871	}
   872	
   873	func TestBadVerbRecursion(t *testing.T) {
   874		failed := false
   875		r := Recur{3, &failed}
   876		Sprintf("recur@%p value: %d\n", &r, r.i)
   877		if failed {
   878			t.Error("fail with pointer")
   879		}
   880		failed = false
   881		r = Recur{4, &failed}
   882		Sprintf("recur@%p, value: %d\n", r, r.i)
   883		if failed {
   884			t.Error("fail with value")
   885		}
   886	}
   887	
   888	func TestIsSpace(t *testing.T) {
   889		// This tests the internal isSpace function.
   890		// IsSpace = isSpace is defined in export_test.go.
   891		for i := rune(0); i <= unicode.MaxRune; i++ {
   892			if IsSpace(i) != unicode.IsSpace(i) {
   893				t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
   894			}
   895		}
   896	}
   897	
   898	func TestNilDoesNotBecomeTyped(t *testing.T) {
   899		type A struct{}
   900		type B struct{}
   901		var a *A = nil
   902		var b B = B{}
   903		got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil)
   904		const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
   905		if got != expect {
   906			t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
   907		}
   908	}

View as plain text