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

View as plain text