github.com/liquid-dev/text@v0.3.3-liquid/message/fmt_test.go (about)

     1  // Copyright 2017 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 message
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"math"
    12  	"reflect"
    13  	"runtime"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/liquid-dev/text/language"
    19  )
    20  
    21  type (
    22  	renamedBool       bool
    23  	renamedInt        int
    24  	renamedInt8       int8
    25  	renamedInt16      int16
    26  	renamedInt32      int32
    27  	renamedInt64      int64
    28  	renamedUint       uint
    29  	renamedUint8      uint8
    30  	renamedUint16     uint16
    31  	renamedUint32     uint32
    32  	renamedUint64     uint64
    33  	renamedUintptr    uintptr
    34  	renamedString     string
    35  	renamedBytes      []byte
    36  	renamedFloat32    float32
    37  	renamedFloat64    float64
    38  	renamedComplex64  complex64
    39  	renamedComplex128 complex128
    40  )
    41  
    42  func TestFmtInterface(t *testing.T) {
    43  	p := NewPrinter(language.Und)
    44  	var i1 interface{}
    45  	i1 = "abc"
    46  	s := p.Sprintf("%s", i1)
    47  	if s != "abc" {
    48  		t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
    49  	}
    50  }
    51  
    52  var (
    53  	NaN    = math.NaN()
    54  	posInf = math.Inf(1)
    55  	negInf = math.Inf(-1)
    56  
    57  	intVar = 0
    58  
    59  	array  = [5]int{1, 2, 3, 4, 5}
    60  	iarray = [4]interface{}{1, "hello", 2.5, nil}
    61  	slice  = array[:]
    62  	islice = iarray[:]
    63  )
    64  
    65  type A struct {
    66  	i int
    67  	j uint
    68  	s string
    69  	x []int
    70  }
    71  
    72  type I int
    73  
    74  func (i I) String() string {
    75  	p := NewPrinter(language.Und)
    76  	return p.Sprintf("<%d>", int(i))
    77  }
    78  
    79  type B struct {
    80  	I I
    81  	j int
    82  }
    83  
    84  type C struct {
    85  	i int
    86  	B
    87  }
    88  
    89  type F int
    90  
    91  func (f F) Format(s fmt.State, c rune) {
    92  	p := NewPrinter(language.Und)
    93  	p.Fprintf(s, "<%c=F(%d)>", c, int(f))
    94  }
    95  
    96  type G int
    97  
    98  func (g G) GoString() string {
    99  	p := NewPrinter(language.Und)
   100  	return p.Sprintf("GoString(%d)", int(g))
   101  }
   102  
   103  type S struct {
   104  	F F // a struct field that Formats
   105  	G G // a struct field that GoStrings
   106  }
   107  
   108  type SI struct {
   109  	I interface{}
   110  }
   111  
   112  // P is a type with a String method with pointer receiver for testing %p.
   113  type P int
   114  
   115  var pValue P
   116  
   117  func (p *P) String() string {
   118  	return "String(p)"
   119  }
   120  
   121  var barray = [5]renamedUint8{1, 2, 3, 4, 5}
   122  var bslice = barray[:]
   123  
   124  type byteStringer byte
   125  
   126  func (byteStringer) String() string {
   127  	return "X"
   128  }
   129  
   130  var byteStringerSlice = []byteStringer{'h', 'e', 'l', 'l', 'o'}
   131  
   132  type byteFormatter byte
   133  
   134  func (byteFormatter) Format(f fmt.State, _ rune) {
   135  	p := NewPrinter(language.Und)
   136  	p.Fprint(f, "X")
   137  }
   138  
   139  var byteFormatterSlice = []byteFormatter{'h', 'e', 'l', 'l', 'o'}
   140  
   141  var fmtTests = []struct {
   142  	fmt string
   143  	val interface{}
   144  	out string
   145  }{
   146  	// The behavior of the following tests differs from that of the fmt package.
   147  
   148  	// Unlike with the fmt package, it is okay to have extra arguments for
   149  	// strings without format parameters. This is because it is impossible to
   150  	// distinguish between reordered or ordered format strings in this case.
   151  	// (For reordered format strings it is okay to not use arguments.)
   152  	{"", nil, ""},
   153  	{"", 2, ""},
   154  	{"no args", "hello", "no args"},
   155  
   156  	{"%017091901790959340919092959340919017929593813360", 0, "%!(NOVERB)"},
   157  	{"%184467440737095516170v", 0, "%!(NOVERB)"},
   158  	// Extra argument errors should format without flags set.
   159  	{"%010.2", "12345", "%!(NOVERB)"},
   160  
   161  	// Some key other differences, asides from localized values:
   162  	// - NaN values should not use affixes; so no signs (CLDR requirement)
   163  	// - Infinity uses patterns, so signs may be different (CLDR requirement)
   164  	// - The # flag is used to disable localization.
   165  
   166  	// All following tests are analogous to those of the fmt package, but with
   167  	// localized numbers when appropriate.
   168  	{"%d", 12345, "12,345"},
   169  	{"%v", 12345, "12,345"},
   170  	{"%t", true, "true"},
   171  
   172  	// basic string
   173  	{"%s", "abc", "abc"},
   174  	{"%q", "abc", `"abc"`},
   175  	{"%x", "abc", "616263"},
   176  	{"%x", "\xff\xf0\x0f\xff", "fff00fff"},
   177  	{"%X", "\xff\xf0\x0f\xff", "FFF00FFF"},
   178  	{"%x", "", ""},
   179  	{"% x", "", ""},
   180  	{"%#x", "", ""},
   181  	{"%# x", "", ""},
   182  	{"%x", "xyz", "78797a"},
   183  	{"%X", "xyz", "78797A"},
   184  	{"% x", "xyz", "78 79 7a"},
   185  	{"% X", "xyz", "78 79 7A"},
   186  	{"%#x", "xyz", "0x78797a"},
   187  	{"%#X", "xyz", "0X78797A"},
   188  	{"%# x", "xyz", "0x78 0x79 0x7a"},
   189  	{"%# X", "xyz", "0X78 0X79 0X7A"},
   190  
   191  	// basic bytes
   192  	{"%s", []byte("abc"), "abc"},
   193  	{"%s", [3]byte{'a', 'b', 'c'}, "abc"},
   194  	{"%s", &[3]byte{'a', 'b', 'c'}, "&abc"},
   195  	{"%q", []byte("abc"), `"abc"`},
   196  	{"%x", []byte("abc"), "616263"},
   197  	{"%x", []byte("\xff\xf0\x0f\xff"), "fff00fff"},
   198  	{"%X", []byte("\xff\xf0\x0f\xff"), "FFF00FFF"},
   199  	{"%x", []byte(""), ""},
   200  	{"% x", []byte(""), ""},
   201  	{"%#x", []byte(""), ""},
   202  	{"%# x", []byte(""), ""},
   203  	{"%x", []byte("xyz"), "78797a"},
   204  	{"%X", []byte("xyz"), "78797A"},
   205  	{"% x", []byte("xyz"), "78 79 7a"},
   206  	{"% X", []byte("xyz"), "78 79 7A"},
   207  	{"%#x", []byte("xyz"), "0x78797a"},
   208  	{"%#X", []byte("xyz"), "0X78797A"},
   209  	{"%# x", []byte("xyz"), "0x78 0x79 0x7a"},
   210  	{"%# X", []byte("xyz"), "0X78 0X79 0X7A"},
   211  
   212  	// escaped strings
   213  	{"%q", "", `""`},
   214  	{"%#q", "", "``"},
   215  	{"%q", "\"", `"\""`},
   216  	{"%#q", "\"", "`\"`"},
   217  	{"%q", "`", `"` + "`" + `"`},
   218  	{"%#q", "`", `"` + "`" + `"`},
   219  	{"%q", "\n", `"\n"`},
   220  	{"%#q", "\n", `"\n"`},
   221  	{"%q", `\n`, `"\\n"`},
   222  	{"%#q", `\n`, "`\\n`"},
   223  	{"%q", "abc", `"abc"`},
   224  	{"%#q", "abc", "`abc`"},
   225  	{"%q", "日本語", `"日本語"`},
   226  	{"%+q", "日本語", `"\u65e5\u672c\u8a9e"`},
   227  	{"%#q", "日本語", "`日本語`"},
   228  	{"%#+q", "日本語", "`日本語`"},
   229  	{"%q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
   230  	{"%+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
   231  	{"%#q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
   232  	{"%#+q", "\a\b\f\n\r\t\v\"\\", `"\a\b\f\n\r\t\v\"\\"`},
   233  	{"%q", "☺", `"☺"`},
   234  	{"% q", "☺", `"☺"`}, // The space modifier should have no effect.
   235  	{"%+q", "☺", `"\u263a"`},
   236  	{"%#q", "☺", "`☺`"},
   237  	{"%#+q", "☺", "`☺`"},
   238  	{"%10q", "⌘", `       "⌘"`},
   239  	{"%+10q", "⌘", `  "\u2318"`},
   240  	{"%-10q", "⌘", `"⌘"       `},
   241  	{"%+-10q", "⌘", `"\u2318"  `},
   242  	{"%010q", "⌘", `0000000"⌘"`},
   243  	{"%+010q", "⌘", `00"\u2318"`},
   244  	{"%-010q", "⌘", `"⌘"       `}, // 0 has no effect when - is present.
   245  	{"%+-010q", "⌘", `"\u2318"  `},
   246  	{"%#8q", "\n", `    "\n"`},
   247  	{"%#+8q", "\r", `    "\r"`},
   248  	{"%#-8q", "\t", "`	`     "},
   249  	{"%#+-8q", "\b", `"\b"    `},
   250  	{"%q", "abc\xffdef", `"abc\xffdef"`},
   251  	{"%+q", "abc\xffdef", `"abc\xffdef"`},
   252  	{"%#q", "abc\xffdef", `"abc\xffdef"`},
   253  	{"%#+q", "abc\xffdef", `"abc\xffdef"`},
   254  	// Runes that are not printable.
   255  	{"%q", "\U0010ffff", `"\U0010ffff"`},
   256  	{"%+q", "\U0010ffff", `"\U0010ffff"`},
   257  	{"%#q", "\U0010ffff", "`􏿿`"},
   258  	{"%#+q", "\U0010ffff", "`􏿿`"},
   259  	// Runes that are not valid.
   260  	{"%q", string(0x110000), `"�"`},
   261  	{"%+q", string(0x110000), `"\ufffd"`},
   262  	{"%#q", string(0x110000), "`�`"},
   263  	{"%#+q", string(0x110000), "`�`"},
   264  
   265  	// characters
   266  	{"%c", uint('x'), "x"},
   267  	{"%c", 0xe4, "ä"},
   268  	{"%c", 0x672c, "本"},
   269  	{"%c", '日', "日"},
   270  	{"%.0c", '⌘', "⌘"}, // Specifying precision should have no effect.
   271  	{"%3c", '⌘', "  ⌘"},
   272  	{"%-3c", '⌘', "⌘  "},
   273  	// Runes that are not printable.
   274  	{"%c", '\U00000e00', "\u0e00"},
   275  	{"%c", '\U0010ffff', "\U0010ffff"},
   276  	// Runes that are not valid.
   277  	{"%c", -1, "�"},
   278  	{"%c", 0xDC80, "�"},
   279  	{"%c", rune(0x110000), "�"},
   280  	{"%c", int64(0xFFFFFFFFF), "�"},
   281  	{"%c", uint64(0xFFFFFFFFF), "�"},
   282  
   283  	// escaped characters
   284  	{"%q", uint(0), `'\x00'`},
   285  	{"%+q", uint(0), `'\x00'`},
   286  	{"%q", '"', `'"'`},
   287  	{"%+q", '"', `'"'`},
   288  	{"%q", '\'', `'\''`},
   289  	{"%+q", '\'', `'\''`},
   290  	{"%q", '`', "'`'"},
   291  	{"%+q", '`', "'`'"},
   292  	{"%q", 'x', `'x'`},
   293  	{"%+q", 'x', `'x'`},
   294  	{"%q", 'ÿ', `'ÿ'`},
   295  	{"%+q", 'ÿ', `'\u00ff'`},
   296  	{"%q", '\n', `'\n'`},
   297  	{"%+q", '\n', `'\n'`},
   298  	{"%q", '☺', `'☺'`},
   299  	{"%+q", '☺', `'\u263a'`},
   300  	{"% q", '☺', `'☺'`},  // The space modifier should have no effect.
   301  	{"%.0q", '☺', `'☺'`}, // Specifying precision should have no effect.
   302  	{"%10q", '⌘', `       '⌘'`},
   303  	{"%+10q", '⌘', `  '\u2318'`},
   304  	{"%-10q", '⌘', `'⌘'       `},
   305  	{"%+-10q", '⌘', `'\u2318'  `},
   306  	{"%010q", '⌘', `0000000'⌘'`},
   307  	{"%+010q", '⌘', `00'\u2318'`},
   308  	{"%-010q", '⌘', `'⌘'       `}, // 0 has no effect when - is present.
   309  	{"%+-010q", '⌘', `'\u2318'  `},
   310  	// Runes that are not printable.
   311  	{"%q", '\U00000e00', `'\u0e00'`},
   312  	{"%q", '\U0010ffff', `'\U0010ffff'`},
   313  	// Runes that are not valid.
   314  	{"%q", int32(-1), "%!q(int32=-1)"},
   315  	{"%q", 0xDC80, `'�'`},
   316  	{"%q", rune(0x110000), "%!q(int32=1,114,112)"},
   317  	{"%q", int64(0xFFFFFFFFF), "%!q(int64=68,719,476,735)"},
   318  	{"%q", uint64(0xFFFFFFFFF), "%!q(uint64=68,719,476,735)"},
   319  
   320  	// width
   321  	{"%5s", "abc", "  abc"},
   322  	{"%2s", "\u263a", " ☺"},
   323  	{"%-5s", "abc", "abc  "},
   324  	{"%-8q", "abc", `"abc"   `},
   325  	{"%05s", "abc", "00abc"},
   326  	{"%08q", "abc", `000"abc"`},
   327  	{"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
   328  	{"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
   329  	{"%.0s", "日本語日本語", ""},
   330  	{"%.5s", "日本語日本語", "日本語日本"},
   331  	{"%.10s", "日本語日本語", "日本語日本語"},
   332  	{"%.5s", []byte("日本語日本語"), "日本語日本"},
   333  	{"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
   334  	{"%.5x", "abcdefghijklmnopqrstuvwxyz", "6162636465"},
   335  	{"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
   336  	{"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), "6162636465"},
   337  	{"%.3q", "日本語日本語", `"日本語"`},
   338  	{"%.3q", []byte("日本語日本語"), `"日本語"`},
   339  	{"%.1q", "日本語", `"日"`},
   340  	{"%.1q", []byte("日本語"), `"日"`},
   341  	{"%.1x", "日本語", "e6"},
   342  	{"%.1X", []byte("日本語"), "E6"},
   343  	{"%10.1q", "日本語日本語", `       "日"`},
   344  	{"%10v", nil, "     <nil>"},
   345  	{"%-10v", nil, "<nil>     "},
   346  
   347  	// integers
   348  	{"%d", uint(12345), "12,345"},
   349  	{"%d", int(-12345), "-12,345"},
   350  	{"%d", ^uint8(0), "255"},
   351  	{"%d", ^uint16(0), "65,535"},
   352  	{"%d", ^uint32(0), "4,294,967,295"},
   353  	{"%d", ^uint64(0), "18,446,744,073,709,551,615"},
   354  	{"%d", int8(-1 << 7), "-128"},
   355  	{"%d", int16(-1 << 15), "-32,768"},
   356  	{"%d", int32(-1 << 31), "-2,147,483,648"},
   357  	{"%d", int64(-1 << 63), "-9,223,372,036,854,775,808"},
   358  	{"%.d", 0, ""},
   359  	{"%.0d", 0, ""},
   360  	{"%6.0d", 0, "      "},
   361  	{"%06.0d", 0, "      "},
   362  	{"% d", 12345, " 12,345"},
   363  	{"%+d", 12345, "+12,345"},
   364  	{"%+d", -12345, "-12,345"},
   365  	{"%b", 7, "111"},
   366  	{"%b", -6, "-110"},
   367  	{"%b", ^uint32(0), "11111111111111111111111111111111"},
   368  	{"%b", ^uint64(0), "1111111111111111111111111111111111111111111111111111111111111111"},
   369  	{"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
   370  	{"%o", 01234, "1234"},
   371  	{"%#o", 01234, "01234"},
   372  	{"%o", ^uint32(0), "37777777777"},
   373  	{"%o", ^uint64(0), "1777777777777777777777"},
   374  	{"%#X", 0, "0X0"},
   375  	{"%x", 0x12abcdef, "12abcdef"},
   376  	{"%X", 0x12abcdef, "12ABCDEF"},
   377  	{"%x", ^uint32(0), "ffffffff"},
   378  	{"%X", ^uint64(0), "FFFFFFFFFFFFFFFF"},
   379  	{"%.20b", 7, "00000000000000000111"},
   380  	{"%10d", 12345, "    12,345"},
   381  	{"%10d", -12345, "   -12,345"},
   382  	{"%+10d", 12345, "   +12,345"},
   383  	{"%010d", 12345, "0,000,012,345"},
   384  	{"%010d", -12345, "-0,000,012,345"},
   385  	{"%20.8d", 1234, "          00,001,234"},
   386  	{"%20.8d", -1234, "         -00,001,234"},
   387  	{"%020.8d", 1234, "          00,001,234"},
   388  	{"%020.8d", -1234, "         -00,001,234"},
   389  	{"%-20.8d", 1234, "00,001,234          "},
   390  	{"%-20.8d", -1234, "-00,001,234         "},
   391  	{"%-#20.8x", 0x1234abc, "0x01234abc          "},
   392  	{"%-#20.8X", 0x1234abc, "0X01234ABC          "},
   393  	{"%-#20.8o", 01234, "00001234            "},
   394  
   395  	// Test correct f.intbuf overflow checks.
   396  	{"%068d", 1, "00," + strings.Repeat("000,", 21) + "001"},
   397  	{"%068d", -1, "-00," + strings.Repeat("000,", 21) + "001"},
   398  	{"%#.68x", 42, zeroFill("0x", 68, "2a")},
   399  	{"%.68d", -42, "-00," + strings.Repeat("000,", 21) + "042"},
   400  	{"%+.68d", 42, "+00," + strings.Repeat("000,", 21) + "042"},
   401  	{"% .68d", 42, " 00," + strings.Repeat("000,", 21) + "042"},
   402  	{"% +.68d", 42, "+00," + strings.Repeat("000,", 21) + "042"},
   403  
   404  	// unicode format
   405  	{"%U", 0, "U+0000"},
   406  	{"%U", -1, "U+FFFFFFFFFFFFFFFF"},
   407  	{"%U", '\n', `U+000A`},
   408  	{"%#U", '\n', `U+000A`},
   409  	{"%+U", 'x', `U+0078`},       // Plus flag should have no effect.
   410  	{"%# U", 'x', `U+0078 'x'`},  // Space flag should have no effect.
   411  	{"%#.2U", 'x', `U+0078 'x'`}, // Precisions below 4 should print 4 digits.
   412  	{"%U", '\u263a', `U+263A`},
   413  	{"%#U", '\u263a', `U+263A '☺'`},
   414  	{"%U", '\U0001D6C2', `U+1D6C2`},
   415  	{"%#U", '\U0001D6C2', `U+1D6C2 '𝛂'`},
   416  	{"%#14.6U", '⌘', "  U+002318 '⌘'"},
   417  	{"%#-14.6U", '⌘', "U+002318 '⌘'  "},
   418  	{"%#014.6U", '⌘', "  U+002318 '⌘'"},
   419  	{"%#-014.6U", '⌘', "U+002318 '⌘'  "},
   420  	{"%.68U", uint(42), zeroFill("U+", 68, "2A")},
   421  	{"%#.68U", '日', zeroFill("U+", 68, "65E5") + " '日'"},
   422  
   423  	// floats
   424  	{"%+.3e", 0.0, "+0.000\u202f×\u202f10⁰⁰"},
   425  	{"%+.3e", 1.0, "+1.000\u202f×\u202f10⁰⁰"},
   426  	{"%+.3f", -1.0, "-1.000"},
   427  	{"%+.3F", -1.0, "-1.000"},
   428  	{"%+.3F", float32(-1.0), "-1.000"},
   429  	{"%+07.2f", 1.0, "+001.00"},
   430  	{"%+07.2f", -1.0, "-001.00"},
   431  	{"%-07.2f", 1.0, "1.00   "},
   432  	{"%-07.2f", -1.0, "-1.00  "},
   433  	{"%+-07.2f", 1.0, "+1.00  "},
   434  	{"%+-07.2f", -1.0, "-1.00  "},
   435  	{"%-+07.2f", 1.0, "+1.00  "},
   436  	{"%-+07.2f", -1.0, "-1.00  "},
   437  	{"%+10.2f", +1.0, "     +1.00"},
   438  	{"%+10.2f", -1.0, "     -1.00"},
   439  	{"% .3E", -1.0, "-1.000\u202f×\u202f10⁰⁰"},
   440  	{"% .3e", 1.0, " 1.000\u202f×\u202f10⁰⁰"},
   441  	{"%+.3g", 0.0, "+0"},
   442  	{"%+.3g", 1.0, "+1"},
   443  	{"%+.3g", -1.0, "-1"},
   444  	{"% .3g", -1.0, "-1"},
   445  	{"% .3g", 1.0, " 1"},
   446  	{"%b", float32(1.0), "8388608p-23"},
   447  	{"%b", 1.0, "4503599627370496p-52"},
   448  	// Test sharp flag used with floats.
   449  	{"%#g", 1e-323, "1.00000e-323"},
   450  	{"%#g", -1.0, "-1.00000"},
   451  	{"%#g", 1.1, "1.10000"},
   452  	{"%#g", 123456.0, "123456."},
   453  	{"%#g", 1234567.0, "1.234567e+06"},
   454  	{"%#g", 1230000.0, "1.23000e+06"},
   455  	{"%#g", 1000000.0, "1.00000e+06"},
   456  	{"%#.0f", 1.0, "1."},
   457  	{"%#.0e", 1.0, "1.e+00"},
   458  	{"%#.0g", 1.0, "1."},
   459  	{"%#.0g", 1100000.0, "1.e+06"},
   460  	{"%#.4f", 1.0, "1.0000"},
   461  	{"%#.4e", 1.0, "1.0000e+00"},
   462  	{"%#.4g", 1.0, "1.000"},
   463  	{"%#.4g", 100000.0, "1.000e+05"},
   464  	{"%#.0f", 123.0, "123."},
   465  	{"%#.0e", 123.0, "1.e+02"},
   466  	{"%#.0g", 123.0, "1.e+02"},
   467  	{"%#.4f", 123.0, "123.0000"},
   468  	{"%#.4e", 123.0, "1.2300e+02"},
   469  	{"%#.4g", 123.0, "123.0"},
   470  	{"%#.4g", 123000.0, "1.230e+05"},
   471  	{"%#9.4g", 1.0, "    1.000"},
   472  	// The sharp flag has no effect for binary float format.
   473  	{"%#b", 1.0, "4503599627370496p-52"},
   474  	// Precision has no effect for binary float format.
   475  	{"%.4b", float32(1.0), "8388608p-23"},
   476  	{"%.4b", -1.0, "-4503599627370496p-52"},
   477  	// Test correct f.intbuf boundary checks.
   478  	{"%.68f", 1.0, zeroFill("1.", 68, "")},
   479  	{"%.68f", -1.0, zeroFill("-1.", 68, "")},
   480  	// float infinites and NaNs
   481  	{"%f", posInf, "∞"},
   482  	{"%.1f", negInf, "-∞"},
   483  	{"% f", NaN, "NaN"},
   484  	{"%20f", posInf, "                   ∞"},
   485  	{"% 20F", posInf, "                   ∞"},
   486  	{"% 20e", negInf, "                  -∞"},
   487  	{"%+20E", negInf, "                  -∞"},
   488  	{"% +20g", negInf, "                  -∞"},
   489  	{"%+-20G", posInf, "+∞                  "},
   490  	{"%20e", NaN, "                 NaN"},
   491  	{"% +20E", NaN, "                 NaN"},
   492  	{"% -20g", NaN, "NaN                 "},
   493  	{"%+-20G", NaN, "NaN                 "},
   494  	// Zero padding does not apply to infinities and NaN.
   495  	{"%+020e", posInf, "                  +∞"},
   496  	{"%-020f", negInf, "-∞                  "},
   497  	{"%-020E", NaN, "NaN                 "},
   498  
   499  	// complex values
   500  	{"%.f", 0i, "(0+0i)"},
   501  	{"% .f", 0i, "( 0+0i)"},
   502  	{"%+.f", 0i, "(+0+0i)"},
   503  	{"% +.f", 0i, "(+0+0i)"},
   504  	{"%+.3e", 0i, "(+0.000\u202f×\u202f10⁰⁰+0.000\u202f×\u202f10⁰⁰i)"},
   505  	{"%+.3f", 0i, "(+0.000+0.000i)"},
   506  	{"%+.3g", 0i, "(+0+0i)"},
   507  	{"%+.3e", 1 + 2i, "(+1.000\u202f×\u202f10⁰⁰+2.000\u202f×\u202f10⁰⁰i)"},
   508  	{"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
   509  	{"%+.3g", 1 + 2i, "(+1+2i)"},
   510  	{"%.3e", 0i, "(0.000\u202f×\u202f10⁰⁰+0.000\u202f×\u202f10⁰⁰i)"},
   511  	{"%.3f", 0i, "(0.000+0.000i)"},
   512  	{"%.3F", 0i, "(0.000+0.000i)"},
   513  	{"%.3F", complex64(0i), "(0.000+0.000i)"},
   514  	{"%.3g", 0i, "(0+0i)"},
   515  	{"%.3e", 1 + 2i, "(1.000\u202f×\u202f10⁰⁰+2.000\u202f×\u202f10⁰⁰i)"},
   516  	{"%.3f", 1 + 2i, "(1.000+2.000i)"},
   517  	{"%.3g", 1 + 2i, "(1+2i)"},
   518  	{"%.3e", -1 - 2i, "(-1.000\u202f×\u202f10⁰⁰-2.000\u202f×\u202f10⁰⁰i)"},
   519  	{"%.3f", -1 - 2i, "(-1.000-2.000i)"},
   520  	{"%.3g", -1 - 2i, "(-1-2i)"},
   521  	{"% .3E", -1 - 2i, "(-1.000\u202f×\u202f10⁰⁰-2.000\u202f×\u202f10⁰⁰i)"},
   522  	{"%+.3g", 1 + 2i, "(+1+2i)"},
   523  	{"%+.3g", complex64(1 + 2i), "(+1+2i)"},
   524  	{"%#g", 1 + 2i, "(1.00000+2.00000i)"},
   525  	{"%#g", 123456 + 789012i, "(123456.+789012.i)"},
   526  	{"%#g", 1e-10i, "(0.00000+1.00000e-10i)"},
   527  	{"%#g", -1e10 - 1.11e100i, "(-1.00000e+10-1.11000e+100i)"},
   528  	{"%#.0f", 1.23 + 1.0i, "(1.+1.i)"},
   529  	{"%#.0e", 1.23 + 1.0i, "(1.e+00+1.e+00i)"},
   530  	{"%#.0g", 1.23 + 1.0i, "(1.+1.i)"},
   531  	{"%#.0g", 0 + 100000i, "(0.+1.e+05i)"},
   532  	{"%#.0g", 1230000 + 0i, "(1.e+06+0.i)"},
   533  	{"%#.4f", 1 + 1.23i, "(1.0000+1.2300i)"},
   534  	{"%#.4e", 123 + 1i, "(1.2300e+02+1.0000e+00i)"},
   535  	{"%#.4g", 123 + 1.23i, "(123.0+1.230i)"},
   536  	{"%#12.5g", 0 + 100000i, "(      0.0000 +1.0000e+05i)"},
   537  	{"%#12.5g", 1230000 - 0i, "(  1.2300e+06     +0.0000i)"},
   538  	{"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
   539  	{"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
   540  	// The sharp flag has no effect for binary complex format.
   541  	{"%#b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
   542  	// Precision has no effect for binary complex format.
   543  	{"%.4b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
   544  	{"%.4b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
   545  	// complex infinites and NaNs
   546  	{"%f", complex(posInf, posInf), "(∞+∞i)"},
   547  	{"%f", complex(negInf, negInf), "(-∞-∞i)"},
   548  	{"%f", complex(NaN, NaN), "(NaN+NaNi)"},
   549  	{"%.1f", complex(posInf, posInf), "(∞+∞i)"},
   550  	{"% f", complex(posInf, posInf), "( ∞+∞i)"},
   551  	{"% f", complex(negInf, negInf), "(-∞-∞i)"},
   552  	{"% f", complex(NaN, NaN), "(NaN+NaNi)"},
   553  	{"%8e", complex(posInf, posInf), "(       ∞      +∞i)"},
   554  	{"% 8E", complex(posInf, posInf), "(       ∞      +∞i)"},
   555  	{"%+8f", complex(negInf, negInf), "(      -∞      -∞i)"},
   556  	{"% +8g", complex(negInf, negInf), "(      -∞      -∞i)"}, // TODO(g)
   557  	{"% -8G", complex(NaN, NaN), "(NaN     +NaN    i)"},
   558  	{"%+-8b", complex(NaN, NaN), "(+NaN    +NaN    i)"},
   559  	// Zero padding does not apply to infinities and NaN.
   560  	{"%08f", complex(posInf, posInf), "(       ∞      +∞i)"},
   561  	{"%-08g", complex(negInf, negInf), "(-∞      -∞      i)"},
   562  	{"%-08G", complex(NaN, NaN), "(NaN     +NaN    i)"},
   563  
   564  	// old test/fmt_test.go
   565  	{"%e", 1.0, "1.000000\u202f×\u202f10⁰⁰"},
   566  	{"%e", 1234.5678e3, "1.234568\u202f×\u202f10⁰⁶"},
   567  	{"%e", 1234.5678e-8, "1.234568\u202f×\u202f10⁻⁰⁵"},
   568  	{"%e", -7.0, "-7.000000\u202f×\u202f10⁰⁰"},
   569  	{"%e", -1e-9, "-1.000000\u202f×\u202f10⁻⁰⁹"},
   570  	{"%f", 1234.5678e3, "1,234,567.800000"},
   571  	{"%f", 1234.5678e-8, "0.000012"},
   572  	{"%f", -7.0, "-7.000000"},
   573  	{"%f", -1e-9, "-0.000000"},
   574  	{"%g", 1234.5678e3, "1.2345678\u202f×\u202f10⁰⁶"},
   575  	{"%g", float32(1234.5678e3), "1.2345678\u202f×\u202f10⁰⁶"},
   576  	{"%g", 1234.5678e-8, "1.2345678\u202f×\u202f10⁻⁰⁵"},
   577  	{"%g", -7.0, "-7"},
   578  	{"%g", -1e-9, "-1\u202f×\u202f10⁻⁰⁹"},
   579  	{"%g", float32(-1e-9), "-1\u202f×\u202f10⁻⁰⁹"},
   580  	{"%E", 1.0, "1.000000\u202f×\u202f10⁰⁰"},
   581  	{"%E", 1234.5678e3, "1.234568\u202f×\u202f10⁰⁶"},
   582  	{"%E", 1234.5678e-8, "1.234568\u202f×\u202f10⁻⁰⁵"},
   583  	{"%E", -7.0, "-7.000000\u202f×\u202f10⁰⁰"},
   584  	{"%E", -1e-9, "-1.000000\u202f×\u202f10⁻⁰⁹"},
   585  	{"%G", 1234.5678e3, "1.2345678\u202f×\u202f10⁰⁶"},
   586  	{"%G", float32(1234.5678e3), "1.2345678\u202f×\u202f10⁰⁶"},
   587  	{"%G", 1234.5678e-8, "1.2345678\u202f×\u202f10⁻⁰⁵"},
   588  	{"%G", -7.0, "-7"},
   589  	{"%G", -1e-9, "-1\u202f×\u202f10⁻⁰⁹"},
   590  	{"%G", float32(-1e-9), "-1\u202f×\u202f10⁻⁰⁹"},
   591  	{"%20.5s", "qwertyuiop", "               qwert"},
   592  	{"%.5s", "qwertyuiop", "qwert"},
   593  	{"%-20.5s", "qwertyuiop", "qwert               "},
   594  	{"%20c", 'x', "                   x"},
   595  	{"%-20c", 'x', "x                   "},
   596  	{"%20.6e", 1.2345e3, "     1.234500\u202f×\u202f10⁰³"},
   597  	{"%20.6e", 1.2345e-3, "    1.234500\u202f×\u202f10⁻⁰³"},
   598  	{"%20e", 1.2345e3, "     1.234500\u202f×\u202f10⁰³"},
   599  	{"%20e", 1.2345e-3, "    1.234500\u202f×\u202f10⁻⁰³"},
   600  	{"%20.8e", 1.2345e3, "   1.23450000\u202f×\u202f10⁰³"},
   601  	{"%20f", 1.23456789e3, "        1,234.567890"},
   602  	{"%20f", 1.23456789e-3, "            0.001235"},
   603  	{"%20f", 12345678901.23456789, "12,345,678,901.234568"},
   604  	{"%-20f", 1.23456789e3, "1,234.567890        "},
   605  	{"%20.8f", 1.23456789e3, "      1,234.56789000"},
   606  	{"%20.8f", 1.23456789e-3, "          0.00123457"},
   607  	{"%g", 1.23456789e3, "1,234.56789"},
   608  	{"%g", 1.23456789e-3, "0.00123456789"},
   609  	{"%g", 1.23456789e20, "1.23456789\u202f×\u202f10²⁰"},
   610  
   611  	// arrays
   612  	{"%v", array, "[1 2 3 4 5]"},
   613  	{"%v", iarray, "[1 hello 2.5 <nil>]"},
   614  	{"%v", barray, "[1 2 3 4 5]"},
   615  	{"%v", &array, "&[1 2 3 4 5]"},
   616  	{"%v", &iarray, "&[1 hello 2.5 <nil>]"},
   617  	{"%v", &barray, "&[1 2 3 4 5]"},
   618  
   619  	// slices
   620  	{"%v", slice, "[1 2 3 4 5]"},
   621  	{"%v", islice, "[1 hello 2.5 <nil>]"},
   622  	{"%v", bslice, "[1 2 3 4 5]"},
   623  	{"%v", &slice, "&[1 2 3 4 5]"},
   624  	{"%v", &islice, "&[1 hello 2.5 <nil>]"},
   625  	{"%v", &bslice, "&[1 2 3 4 5]"},
   626  
   627  	// byte arrays and slices with %b,%c,%d,%o,%U and %v
   628  	{"%b", [3]byte{65, 66, 67}, "[1000001 1000010 1000011]"},
   629  	{"%c", [3]byte{65, 66, 67}, "[A B C]"},
   630  	{"%d", [3]byte{65, 66, 67}, "[65 66 67]"},
   631  	{"%o", [3]byte{65, 66, 67}, "[101 102 103]"},
   632  	{"%U", [3]byte{65, 66, 67}, "[U+0041 U+0042 U+0043]"},
   633  	{"%v", [3]byte{65, 66, 67}, "[65 66 67]"},
   634  	{"%v", [1]byte{123}, "[123]"},
   635  	{"%012v", []byte{}, "[]"},
   636  	{"%#012v", []byte{}, "[]byte{}"},
   637  	{"%6v", []byte{1, 11, 111}, "[     1     11    111]"},
   638  	{"%06v", []byte{1, 11, 111}, "[000001 000011 000111]"},
   639  	{"%-6v", []byte{1, 11, 111}, "[1      11     111   ]"},
   640  	{"%-06v", []byte{1, 11, 111}, "[1      11     111   ]"},
   641  	{"%#v", []byte{1, 11, 111}, "[]byte{0x1, 0xb, 0x6f}"},
   642  	{"%#6v", []byte{1, 11, 111}, "[]byte{   0x1,    0xb,   0x6f}"},
   643  	{"%#06v", []byte{1, 11, 111}, "[]byte{0x000001, 0x00000b, 0x00006f}"},
   644  	{"%#-6v", []byte{1, 11, 111}, "[]byte{0x1   , 0xb   , 0x6f  }"},
   645  	{"%#-06v", []byte{1, 11, 111}, "[]byte{0x1   , 0xb   , 0x6f  }"},
   646  	// f.space should and f.plus should not have an effect with %v.
   647  	{"% v", []byte{1, 11, 111}, "[ 1  11  111]"},
   648  	{"%+v", [3]byte{1, 11, 111}, "[1 11 111]"},
   649  	{"%# -6v", []byte{1, 11, 111}, "[]byte{ 0x1  ,  0xb  ,  0x6f }"},
   650  	{"%#+-6v", [3]byte{1, 11, 111}, "[3]uint8{0x1   , 0xb   , 0x6f  }"},
   651  	// f.space and f.plus should have an effect with %d.
   652  	{"% d", []byte{1, 11, 111}, "[ 1  11  111]"},
   653  	{"%+d", [3]byte{1, 11, 111}, "[+1 +11 +111]"},
   654  	{"%# -6d", []byte{1, 11, 111}, "[ 1      11     111  ]"},
   655  	{"%#+-6d", [3]byte{1, 11, 111}, "[+1     +11    +111  ]"},
   656  
   657  	// floates with %v
   658  	{"%v", 1.2345678, "1.2345678"},
   659  	{"%v", float32(1.2345678), "1.2345678"},
   660  
   661  	// complexes with %v
   662  	{"%v", 1 + 2i, "(1+2i)"},
   663  	{"%v", complex64(1 + 2i), "(1+2i)"},
   664  
   665  	// structs
   666  	{"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
   667  	{"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
   668  
   669  	// +v on structs with Stringable items
   670  	{"%+v", B{1, 2}, `{I:<1> j:2}`},
   671  	{"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
   672  
   673  	// other formats on Stringable items
   674  	{"%s", I(23), `<23>`},
   675  	{"%q", I(23), `"<23>"`},
   676  	{"%x", I(23), `3c32333e`},
   677  	{"%#x", I(23), `0x3c32333e`},
   678  	{"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
   679  	// Stringer applies only to string formats.
   680  	{"%d", I(23), `23`},
   681  	// Stringer applies to the extracted value.
   682  	{"%s", reflect.ValueOf(I(23)), `<23>`},
   683  
   684  	// go syntax
   685  	{"%#v", A{1, 2, "a", []int{1, 2}}, `message.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
   686  	{"%#v", new(byte), "(*uint8)(0xPTR)"},
   687  	{"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
   688  	{"%#v", make(chan int), "(chan int)(0xPTR)"},
   689  	{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
   690  	{"%#v", 1000000000, "1000000000"},
   691  	{"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
   692  	{"%#v", map[string]B{"a": {1, 2}}, `map[string]message.B{"a":message.B{I:1, j:2}}`},
   693  	{"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
   694  	{"%#v", SI{}, `message.SI{I:interface {}(nil)}`},
   695  	{"%#v", []int(nil), `[]int(nil)`},
   696  	{"%#v", []int{}, `[]int{}`},
   697  	{"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
   698  	{"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
   699  	{"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
   700  	{"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
   701  	{"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
   702  	{"%#v", map[int]byte{}, `map[int]uint8{}`},
   703  	{"%#v", "foo", `"foo"`},
   704  	{"%#v", barray, `[5]message.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
   705  	{"%#v", bslice, `[]message.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
   706  	{"%#v", []int32(nil), "[]int32(nil)"},
   707  	{"%#v", 1.2345678, "1.2345678"},
   708  	{"%#v", float32(1.2345678), "1.2345678"},
   709  	// Only print []byte and []uint8 as type []byte if they appear at the top level.
   710  	{"%#v", []byte(nil), "[]byte(nil)"},
   711  	{"%#v", []uint8(nil), "[]byte(nil)"},
   712  	{"%#v", []byte{}, "[]byte{}"},
   713  	{"%#v", []uint8{}, "[]byte{}"},
   714  	{"%#v", reflect.ValueOf([]byte{}), "[]uint8{}"},
   715  	{"%#v", reflect.ValueOf([]uint8{}), "[]uint8{}"},
   716  	{"%#v", &[]byte{}, "&[]uint8{}"},
   717  	{"%#v", &[]byte{}, "&[]uint8{}"},
   718  	{"%#v", [3]byte{}, "[3]uint8{0x0, 0x0, 0x0}"},
   719  	{"%#v", [3]uint8{}, "[3]uint8{0x0, 0x0, 0x0}"},
   720  
   721  	// slices with other formats
   722  	{"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
   723  	{"%x", []int{1, 2, 15}, `[1 2 f]`},
   724  	{"%d", []int{1, 2, 15}, `[1 2 15]`},
   725  	{"%d", []byte{1, 2, 15}, `[1 2 15]`},
   726  	{"%q", []string{"a", "b"}, `["a" "b"]`},
   727  	{"% 02x", []byte{1}, "01"},
   728  	{"% 02x", []byte{1, 2, 3}, "01 02 03"},
   729  
   730  	// Padding with byte slices.
   731  	{"%2x", []byte{}, "  "},
   732  	{"%#2x", []byte{}, "  "},
   733  	{"% 02x", []byte{}, "00"},
   734  	{"%# 02x", []byte{}, "00"},
   735  	{"%-2x", []byte{}, "  "},
   736  	{"%-02x", []byte{}, "  "},
   737  	{"%8x", []byte{0xab}, "      ab"},
   738  	{"% 8x", []byte{0xab}, "      ab"},
   739  	{"%#8x", []byte{0xab}, "    0xab"},
   740  	{"%# 8x", []byte{0xab}, "    0xab"},
   741  	{"%08x", []byte{0xab}, "000000ab"},
   742  	{"% 08x", []byte{0xab}, "000000ab"},
   743  	{"%#08x", []byte{0xab}, "00000xab"},
   744  	{"%# 08x", []byte{0xab}, "00000xab"},
   745  	{"%10x", []byte{0xab, 0xcd}, "      abcd"},
   746  	{"% 10x", []byte{0xab, 0xcd}, "     ab cd"},
   747  	{"%#10x", []byte{0xab, 0xcd}, "    0xabcd"},
   748  	{"%# 10x", []byte{0xab, 0xcd}, " 0xab 0xcd"},
   749  	{"%010x", []byte{0xab, 0xcd}, "000000abcd"},
   750  	{"% 010x", []byte{0xab, 0xcd}, "00000ab cd"},
   751  	{"%#010x", []byte{0xab, 0xcd}, "00000xabcd"},
   752  	{"%# 010x", []byte{0xab, 0xcd}, "00xab 0xcd"},
   753  	{"%-10X", []byte{0xab}, "AB        "},
   754  	{"% -010X", []byte{0xab}, "AB        "},
   755  	{"%#-10X", []byte{0xab, 0xcd}, "0XABCD    "},
   756  	{"%# -010X", []byte{0xab, 0xcd}, "0XAB 0XCD "},
   757  	// Same for strings
   758  	{"%2x", "", "  "},
   759  	{"%#2x", "", "  "},
   760  	{"% 02x", "", "00"},
   761  	{"%# 02x", "", "00"},
   762  	{"%-2x", "", "  "},
   763  	{"%-02x", "", "  "},
   764  	{"%8x", "\xab", "      ab"},
   765  	{"% 8x", "\xab", "      ab"},
   766  	{"%#8x", "\xab", "    0xab"},
   767  	{"%# 8x", "\xab", "    0xab"},
   768  	{"%08x", "\xab", "000000ab"},
   769  	{"% 08x", "\xab", "000000ab"},
   770  	{"%#08x", "\xab", "00000xab"},
   771  	{"%# 08x", "\xab", "00000xab"},
   772  	{"%10x", "\xab\xcd", "      abcd"},
   773  	{"% 10x", "\xab\xcd", "     ab cd"},
   774  	{"%#10x", "\xab\xcd", "    0xabcd"},
   775  	{"%# 10x", "\xab\xcd", " 0xab 0xcd"},
   776  	{"%010x", "\xab\xcd", "000000abcd"},
   777  	{"% 010x", "\xab\xcd", "00000ab cd"},
   778  	{"%#010x", "\xab\xcd", "00000xabcd"},
   779  	{"%# 010x", "\xab\xcd", "00xab 0xcd"},
   780  	{"%-10X", "\xab", "AB        "},
   781  	{"% -010X", "\xab", "AB        "},
   782  	{"%#-10X", "\xab\xcd", "0XABCD    "},
   783  	{"%# -010X", "\xab\xcd", "0XAB 0XCD "},
   784  
   785  	// renamings
   786  	{"%v", renamedBool(true), "true"},
   787  	{"%d", renamedBool(true), "%!d(message.renamedBool=true)"},
   788  	{"%o", renamedInt(8), "10"},
   789  	{"%d", renamedInt8(-9), "-9"},
   790  	{"%v", renamedInt16(10), "10"},
   791  	{"%v", renamedInt32(-11), "-11"},
   792  	{"%X", renamedInt64(255), "FF"},
   793  	{"%v", renamedUint(13), "13"},
   794  	{"%o", renamedUint8(14), "16"},
   795  	{"%X", renamedUint16(15), "F"},
   796  	{"%d", renamedUint32(16), "16"},
   797  	{"%X", renamedUint64(17), "11"},
   798  	{"%o", renamedUintptr(18), "22"},
   799  	{"%x", renamedString("thing"), "7468696e67"},
   800  	{"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
   801  	{"%q", renamedBytes([]byte("hello")), `"hello"`},
   802  	{"%x", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656c6c6f"},
   803  	{"%X", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "68656C6C6F"},
   804  	{"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
   805  	{"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
   806  	{"%v", renamedFloat32(22), "22"},
   807  	{"%v", renamedFloat64(33), "33"},
   808  	{"%v", renamedComplex64(3 + 4i), "(3+4i)"},
   809  	{"%v", renamedComplex128(4 - 3i), "(4-3i)"},
   810  
   811  	// Formatter
   812  	{"%x", F(1), "<x=F(1)>"},
   813  	{"%x", G(2), "2"},
   814  	{"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
   815  
   816  	// GoStringer
   817  	{"%#v", G(6), "GoString(6)"},
   818  	{"%#v", S{F(7), G(8)}, "message.S{F:<v=F(7)>, G:GoString(8)}"},
   819  
   820  	// %T
   821  	{"%T", byte(0), "uint8"},
   822  	{"%T", reflect.ValueOf(nil), "reflect.Value"},
   823  	{"%T", (4 - 3i), "complex128"},
   824  	{"%T", renamedComplex128(4 - 3i), "message.renamedComplex128"},
   825  	{"%T", intVar, "int"},
   826  	{"%6T", &intVar, "  *int"},
   827  	{"%10T", nil, "     <nil>"},
   828  	{"%-10T", nil, "<nil>     "},
   829  
   830  	// %p with pointers
   831  	{"%p", (*int)(nil), "0x0"},
   832  	{"%#p", (*int)(nil), "0"},
   833  	{"%p", &intVar, "0xPTR"},
   834  	{"%#p", &intVar, "PTR"},
   835  	{"%p", &array, "0xPTR"},
   836  	{"%p", &slice, "0xPTR"},
   837  	{"%8.2p", (*int)(nil), "    0x00"},
   838  	{"%-20.16p", &intVar, "0xPTR  "},
   839  	// %p on non-pointers
   840  	{"%p", make(chan int), "0xPTR"},
   841  	{"%p", make(map[int]int), "0xPTR"},
   842  	{"%p", func() {}, "0xPTR"},
   843  	{"%p", 27, "%!p(int=27)"},  // not a pointer at all
   844  	{"%p", nil, "%!p(<nil>)"},  // nil on its own has no type ...
   845  	{"%#p", nil, "%!p(<nil>)"}, // ... and hence is not a pointer type.
   846  	// pointers with specified base
   847  	{"%b", &intVar, "PTR_b"},
   848  	{"%d", &intVar, "PTR_d"},
   849  	{"%o", &intVar, "PTR_o"},
   850  	{"%x", &intVar, "PTR_x"},
   851  	{"%X", &intVar, "PTR_X"},
   852  	// %v on pointers
   853  	{"%v", nil, "<nil>"},
   854  	{"%#v", nil, "<nil>"},
   855  	{"%v", (*int)(nil), "<nil>"},
   856  	{"%#v", (*int)(nil), "(*int)(nil)"},
   857  	{"%v", &intVar, "0xPTR"},
   858  	{"%#v", &intVar, "(*int)(0xPTR)"},
   859  	{"%8.2v", (*int)(nil), "   <nil>"},
   860  	{"%-20.16v", &intVar, "0xPTR  "},
   861  	// string method on pointer
   862  	{"%s", &pValue, "String(p)"}, // String method...
   863  	{"%p", &pValue, "0xPTR"},     // ... is not called with %p.
   864  
   865  	// %d on Stringer should give integer if possible
   866  	{"%s", time.Time{}.Month(), "January"},
   867  	{"%d", time.Time{}.Month(), "1"},
   868  
   869  	// erroneous things
   870  	{"%s %", "hello", "hello %!(NOVERB)"},
   871  	{"%s %.2", "hello", "hello %!(NOVERB)"},
   872  
   873  	// The "<nil>" show up because maps are printed by
   874  	// first obtaining a list of keys and then looking up
   875  	// each key. Since NaNs can be map keys but cannot
   876  	// be fetched directly, the lookup fails and returns a
   877  	// zero reflect.Value, which formats as <nil>.
   878  	// This test is just to check that it shows the two NaNs at all.
   879  	{"%v", map[float64]int{NaN: 1, NaN: 2}, "map[NaN:<nil> NaN:<nil>]"},
   880  
   881  	// Comparison of padding rules with C printf.
   882  	/*
   883  		C program:
   884  		#include <stdio.h>
   885  
   886  		char *format[] = {
   887  			"[%.2f]",
   888  			"[% .2f]",
   889  			"[%+.2f]",
   890  			"[%7.2f]",
   891  			"[% 7.2f]",
   892  			"[%+7.2f]",
   893  			"[% +7.2f]",
   894  			"[%07.2f]",
   895  			"[% 07.2f]",
   896  			"[%+07.2f]",
   897  			"[% +07.2f]"
   898  		};
   899  
   900  		int main(void) {
   901  			int i;
   902  			for(i = 0; i < 11; i++) {
   903  				printf("%s: ", format[i]);
   904  				printf(format[i], 1.0);
   905  				printf(" ");
   906  				printf(format[i], -1.0);
   907  				printf("\n");
   908  			}
   909  		}
   910  
   911  		Output:
   912  			[%.2f]: [1.00] [-1.00]
   913  			[% .2f]: [ 1.00] [-1.00]
   914  			[%+.2f]: [+1.00] [-1.00]
   915  			[%7.2f]: [   1.00] [  -1.00]
   916  			[% 7.2f]: [   1.00] [  -1.00]
   917  			[%+7.2f]: [  +1.00] [  -1.00]
   918  			[% +7.2f]: [  +1.00] [  -1.00]
   919  			[%07.2f]: [0001.00] [-001.00]
   920  			[% 07.2f]: [ 001.00] [-001.00]
   921  			[%+07.2f]: [+001.00] [-001.00]
   922  			[% +07.2f]: [+001.00] [-001.00]
   923  
   924  	*/
   925  	{"%.2f", 1.0, "1.00"},
   926  	{"%.2f", -1.0, "-1.00"},
   927  	{"% .2f", 1.0, " 1.00"},
   928  	{"% .2f", -1.0, "-1.00"},
   929  	{"%+.2f", 1.0, "+1.00"},
   930  	{"%+.2f", -1.0, "-1.00"},
   931  	{"%7.2f", 1.0, "   1.00"},
   932  	{"%7.2f", -1.0, "  -1.00"},
   933  	{"% 7.2f", 1.0, "   1.00"},
   934  	{"% 7.2f", -1.0, "  -1.00"},
   935  	{"%+7.2f", 1.0, "  +1.00"},
   936  	{"%+7.2f", -1.0, "  -1.00"},
   937  	{"% +7.2f", 1.0, "  +1.00"},
   938  	{"% +7.2f", -1.0, "  -1.00"},
   939  	// Padding with 0's indicates minimum number of integer digits minus the
   940  	// period, if present, and minus the sign if it is fixed.
   941  	// TODO: consider making this number the number of significant digits.
   942  	{"%07.2f", 1.0, "0,001.00"},
   943  	{"%07.2f", -1.0, "-0,001.00"},
   944  	{"% 07.2f", 1.0, " 001.00"},
   945  	{"% 07.2f", -1.0, "-001.00"},
   946  	{"%+07.2f", 1.0, "+001.00"},
   947  	{"%+07.2f", -1.0, "-001.00"},
   948  	{"% +07.2f", 1.0, "+001.00"},
   949  	{"% +07.2f", -1.0, "-001.00"},
   950  
   951  	// Complex numbers: exhaustively tested in TestComplexFormatting.
   952  	{"%7.2f", 1 + 2i, "(   1.00  +2.00i)"},
   953  	{"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
   954  
   955  	// Use spaces instead of zero if padding to the right.
   956  	{"%0-5s", "abc", "abc  "},
   957  	{"%-05.1f", 1.0, "1.0  "},
   958  
   959  	// float and complex formatting should not change the padding width
   960  	// for other elements. See issue 14642.
   961  	{"%06v", []interface{}{+10.0, 10}, "[000,010 000,010]"},
   962  	{"%06v", []interface{}{-10.0, 10}, "[-000,010 000,010]"},
   963  	{"%06v", []interface{}{+10.0 + 10i, 10}, "[(000,010+00,010i) 000,010]"},
   964  	{"%06v", []interface{}{-10.0 + 10i, 10}, "[(-000,010+00,010i) 000,010]"},
   965  
   966  	// integer formatting should not alter padding for other elements.
   967  	{"%03.6v", []interface{}{1, 2.0, "x"}, "[000,001 002 00x]"},
   968  	{"%03.0v", []interface{}{0, 2.0, "x"}, "[    002 000]"},
   969  
   970  	// Complex fmt used to leave the plus flag set for future entries in the array
   971  	// causing +2+0i and +3+0i instead of 2+0i and 3+0i.
   972  	{"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
   973  	{"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
   974  
   975  	// Incomplete format specification caused crash.
   976  	{"%.", 3, "%!.(int=3)"},
   977  
   978  	// Padding for complex numbers. Has been bad, then fixed, then bad again.
   979  	{"%+10.2f", +104.66 + 440.51i, "(   +104.66   +440.51i)"},
   980  	{"%+10.2f", -104.66 + 440.51i, "(   -104.66   +440.51i)"},
   981  	{"%+10.2f", +104.66 - 440.51i, "(   +104.66   -440.51i)"},
   982  	{"%+10.2f", -104.66 - 440.51i, "(   -104.66   -440.51i)"},
   983  	{"%010.2f", +104.66 + 440.51i, "(0,000,104.66+000,440.51i)"},
   984  	{"%+010.2f", +104.66 + 440.51i, "(+000,104.66+000,440.51i)"},
   985  	{"%+010.2f", -104.66 + 440.51i, "(-000,104.66+000,440.51i)"},
   986  	{"%+010.2f", +104.66 - 440.51i, "(+000,104.66-000,440.51i)"},
   987  	{"%+010.2f", -104.66 - 440.51i, "(-000,104.66-000,440.51i)"},
   988  
   989  	// []T where type T is a byte with a Stringer method.
   990  	{"%v", byteStringerSlice, "[X X X X X]"},
   991  	{"%s", byteStringerSlice, "hello"},
   992  	{"%q", byteStringerSlice, "\"hello\""},
   993  	{"%x", byteStringerSlice, "68656c6c6f"},
   994  	{"%X", byteStringerSlice, "68656C6C6F"},
   995  	{"%#v", byteStringerSlice, "[]message.byteStringer{0x68, 0x65, 0x6c, 0x6c, 0x6f}"},
   996  
   997  	// And the same for Formatter.
   998  	{"%v", byteFormatterSlice, "[X X X X X]"},
   999  	{"%s", byteFormatterSlice, "hello"},
  1000  	{"%q", byteFormatterSlice, "\"hello\""},
  1001  	{"%x", byteFormatterSlice, "68656c6c6f"},
  1002  	{"%X", byteFormatterSlice, "68656C6C6F"},
  1003  	// This next case seems wrong, but the docs say the Formatter wins here.
  1004  	{"%#v", byteFormatterSlice, "[]message.byteFormatter{X, X, X, X, X}"},
  1005  
  1006  	// reflect.Value handled specially in Go 1.5, making it possible to
  1007  	// see inside non-exported fields (which cannot be accessed with Interface()).
  1008  	// Issue 8965.
  1009  	{"%v", reflect.ValueOf(A{}).Field(0).String(), "<int Value>"}, // Equivalent to the old way.
  1010  	{"%v", reflect.ValueOf(A{}).Field(0), "0"},                    // Sees inside the field.
  1011  
  1012  	// verbs apply to the extracted value too.
  1013  	{"%s", reflect.ValueOf("hello"), "hello"},
  1014  	{"%q", reflect.ValueOf("hello"), `"hello"`},
  1015  	{"%#04x", reflect.ValueOf(256), "0x0100"},
  1016  
  1017  	// invalid reflect.Value doesn't crash.
  1018  	{"%v", reflect.Value{}, "<invalid reflect.Value>"},
  1019  	{"%v", &reflect.Value{}, "<invalid Value>"},
  1020  	{"%v", SI{reflect.Value{}}, "{<invalid Value>}"},
  1021  
  1022  	// Tests to check that not supported verbs generate an error string.
  1023  	{"%☠", nil, "%!☠(<nil>)"},
  1024  	{"%☠", interface{}(nil), "%!☠(<nil>)"},
  1025  	{"%☠", int(0), "%!☠(int=0)"},
  1026  	{"%☠", uint(0), "%!☠(uint=0)"},
  1027  	{"%☠", []byte{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
  1028  	{"%☠", []uint8{0, 1}, "[%!☠(uint8=0) %!☠(uint8=1)]"},
  1029  	{"%☠", [1]byte{0}, "[%!☠(uint8=0)]"},
  1030  	{"%☠", [1]uint8{0}, "[%!☠(uint8=0)]"},
  1031  	{"%☠", "hello", "%!☠(string=hello)"},
  1032  	{"%☠", 1.2345678, "%!☠(float64=1.2345678)"},
  1033  	{"%☠", float32(1.2345678), "%!☠(float32=1.2345678)"},
  1034  	{"%☠", 1.2345678 + 1.2345678i, "%!☠(complex128=(1.2345678+1.2345678i))"},
  1035  	{"%☠", complex64(1.2345678 + 1.2345678i), "%!☠(complex64=(1.2345678+1.2345678i))"},
  1036  	{"%☠", &intVar, "%!☠(*int=0xPTR)"},
  1037  	{"%☠", make(chan int), "%!☠(chan int=0xPTR)"},
  1038  	{"%☠", func() {}, "%!☠(func()=0xPTR)"},
  1039  	{"%☠", reflect.ValueOf(renamedInt(0)), "%!☠(message.renamedInt=0)"},
  1040  	{"%☠", SI{renamedInt(0)}, "{%!☠(message.renamedInt=0)}"},
  1041  	{"%☠", &[]interface{}{I(1), G(2)}, "&[%!☠(message.I=1) %!☠(message.G=2)]"},
  1042  	{"%☠", SI{&[]interface{}{I(1), G(2)}}, "{%!☠(*[]interface {}=&[1 2])}"},
  1043  	{"%☠", reflect.Value{}, "<invalid reflect.Value>"},
  1044  	{"%☠", map[float64]int{NaN: 1}, "map[%!☠(float64=NaN):%!☠(<nil>)]"},
  1045  }
  1046  
  1047  // zeroFill generates zero-filled strings of the specified width. The length
  1048  // of the suffix (but not the prefix) is compensated for in the width calculation.
  1049  func zeroFill(prefix string, width int, suffix string) string {
  1050  	return prefix + strings.Repeat("0", width-len(suffix)) + suffix
  1051  }
  1052  
  1053  func TestSprintf(t *testing.T) {
  1054  	p := NewPrinter(language.Und)
  1055  	for _, tt := range fmtTests {
  1056  		t.Run(fmt.Sprint(tt.fmt, "/", tt.val), func(t *testing.T) {
  1057  			s := p.Sprintf(tt.fmt, tt.val)
  1058  			i := strings.Index(tt.out, "PTR")
  1059  			if i >= 0 && i < len(s) {
  1060  				var pattern, chars string
  1061  				switch {
  1062  				case strings.HasPrefix(tt.out[i:], "PTR_b"):
  1063  					pattern = "PTR_b"
  1064  					chars = "01"
  1065  				case strings.HasPrefix(tt.out[i:], "PTR_o"):
  1066  					pattern = "PTR_o"
  1067  					chars = "01234567"
  1068  				case strings.HasPrefix(tt.out[i:], "PTR_d"):
  1069  					pattern = "PTR_d"
  1070  					chars = "0123456789"
  1071  				case strings.HasPrefix(tt.out[i:], "PTR_x"):
  1072  					pattern = "PTR_x"
  1073  					chars = "0123456789abcdef"
  1074  				case strings.HasPrefix(tt.out[i:], "PTR_X"):
  1075  					pattern = "PTR_X"
  1076  					chars = "0123456789ABCDEF"
  1077  				default:
  1078  					pattern = "PTR"
  1079  					chars = "0123456789abcdefABCDEF"
  1080  				}
  1081  				p := s[:i] + pattern
  1082  				for j := i; j < len(s); j++ {
  1083  					if !strings.ContainsRune(chars, rune(s[j])) {
  1084  						p += s[j:]
  1085  						break
  1086  					}
  1087  				}
  1088  				s = p
  1089  			}
  1090  			if s != tt.out {
  1091  				if _, ok := tt.val.(string); ok {
  1092  					// Don't requote the already-quoted strings.
  1093  					// It's too confusing to read the errors.
  1094  					t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
  1095  				} else {
  1096  					t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
  1097  				}
  1098  			}
  1099  		})
  1100  	}
  1101  }
  1102  
  1103  var f float64
  1104  
  1105  // TestComplexFormatting checks that a complex always formats to the same
  1106  // thing as if done by hand with two singleton prints.
  1107  func TestComplexFormatting(t *testing.T) {
  1108  	var yesNo = []bool{true, false}
  1109  	var values = []float64{1, 0, -1, posInf, negInf, NaN}
  1110  	p := NewPrinter(language.Und)
  1111  	for _, plus := range yesNo {
  1112  		for _, zero := range yesNo {
  1113  			for _, space := range yesNo {
  1114  				for _, char := range "fFeEgG" {
  1115  					realFmt := "%"
  1116  					if zero {
  1117  						realFmt += "0"
  1118  					}
  1119  					if space {
  1120  						realFmt += " "
  1121  					}
  1122  					if plus {
  1123  						realFmt += "+"
  1124  					}
  1125  					realFmt += "10.2"
  1126  					realFmt += string(char)
  1127  					// Imaginary part always has a sign, so force + and ignore space.
  1128  					imagFmt := "%"
  1129  					if zero {
  1130  						imagFmt += "0"
  1131  					}
  1132  					imagFmt += "+"
  1133  					imagFmt += "10.2"
  1134  					imagFmt += string(char)
  1135  					for _, realValue := range values {
  1136  						for _, imagValue := range values {
  1137  							one := p.Sprintf(realFmt, complex(realValue, imagValue))
  1138  							two := p.Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
  1139  							if math.IsNaN(imagValue) {
  1140  								p := len(two) - len("NaNi)") - 1
  1141  								if two[p] == ' ' {
  1142  									two = two[:p] + "+" + two[p+1:]
  1143  								} else {
  1144  									two = two[:p+1] + "+" + two[p+1:]
  1145  								}
  1146  							}
  1147  							if one != two {
  1148  								t.Error(f, one, two)
  1149  							}
  1150  						}
  1151  					}
  1152  				}
  1153  			}
  1154  		}
  1155  	}
  1156  }
  1157  
  1158  type SE []interface{} // slice of empty; notational compactness.
  1159  
  1160  var reorderTests = []struct {
  1161  	format string
  1162  	args   SE
  1163  	out    string
  1164  }{
  1165  	{"%[1]d", SE{1}, "1"},
  1166  	{"%[2]d", SE{2, 1}, "1"},
  1167  	{"%[2]d %[1]d", SE{1, 2}, "2 1"},
  1168  	{"%[2]*[1]d", SE{2, 5}, "    2"},
  1169  	{"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line.
  1170  	{"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
  1171  	{"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
  1172  	{"%10f", SE{12.0}, " 12.000000"},
  1173  	{"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
  1174  	{"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line.
  1175  	{"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
  1176  	{"%6.f", SE{12.0}, "    12"}, //  // Explicit version of next line; empty precision means zero.
  1177  	{"%[1]*.[3]f", SE{6, 3, 12.0}, "    12"},
  1178  	// An actual use! Print the same arguments twice.
  1179  	{"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
  1180  
  1181  	// Erroneous cases.
  1182  	{"%[d", SE{2, 1}, "%!d(BADINDEX)"},
  1183  	{"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
  1184  	{"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
  1185  	{"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
  1186  	{"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
  1187  	{"%[3]", SE{2, 1}, "%!(NOVERB)"},
  1188  	{"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
  1189  	{"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
  1190  	{"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
  1191  	{"%.[2]d", SE{7}, "%!d(BADINDEX)"},
  1192  	{"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
  1193  	{"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
  1194  	{"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
  1195  	{"%.[]", SE{}, "%!](BADINDEX)"},                // Issue 10675
  1196  	{"%.-3d", SE{42}, "%!-(int=42)3d"},             // TODO: Should this set return better error messages?
  1197  	// The following messages are interpreted as if there is no substitution,
  1198  	// in which case it is okay to have extra arguments. This is different
  1199  	// semantics from the fmt package.
  1200  	{"%2147483648d", SE{42}, "%!(NOVERB)"},
  1201  	{"%-2147483648d", SE{42}, "%!(NOVERB)"},
  1202  	{"%.2147483648d", SE{42}, "%!(NOVERB)"},
  1203  }
  1204  
  1205  func TestReorder(t *testing.T) {
  1206  	p := NewPrinter(language.Und)
  1207  	for _, tc := range reorderTests {
  1208  		t.Run(fmt.Sprint(tc.format, "/", tc.args), func(t *testing.T) {
  1209  			s := p.Sprintf(tc.format, tc.args...)
  1210  			if s != tc.out {
  1211  				t.Errorf("Sprintf(%q, %v) = %q want %q", tc.format, tc.args, s, tc.out)
  1212  			}
  1213  		})
  1214  	}
  1215  }
  1216  
  1217  func BenchmarkSprintfPadding(b *testing.B) {
  1218  	b.RunParallel(func(pb *testing.PB) {
  1219  		p := NewPrinter(language.English)
  1220  		for pb.Next() {
  1221  			p.Sprintf("%16f", 1.0)
  1222  		}
  1223  	})
  1224  }
  1225  
  1226  func BenchmarkSprintfEmpty(b *testing.B) {
  1227  	b.RunParallel(func(pb *testing.PB) {
  1228  		p := NewPrinter(language.English)
  1229  		for pb.Next() {
  1230  			p.Sprintf("")
  1231  		}
  1232  	})
  1233  }
  1234  
  1235  func BenchmarkSprintfString(b *testing.B) {
  1236  	b.RunParallel(func(pb *testing.PB) {
  1237  		p := NewPrinter(language.English)
  1238  		for pb.Next() {
  1239  			p.Sprintf("%s", "hello")
  1240  		}
  1241  	})
  1242  }
  1243  
  1244  func BenchmarkSprintfTruncateString(b *testing.B) {
  1245  	b.RunParallel(func(pb *testing.PB) {
  1246  		p := NewPrinter(language.English)
  1247  		for pb.Next() {
  1248  			p.Sprintf("%.3s", "日本語日本語日本語")
  1249  		}
  1250  	})
  1251  }
  1252  
  1253  func BenchmarkSprintfQuoteString(b *testing.B) {
  1254  	b.RunParallel(func(pb *testing.PB) {
  1255  		p := NewPrinter(language.English)
  1256  		for pb.Next() {
  1257  			p.Sprintf("%q", "日本語日本語日本語")
  1258  		}
  1259  	})
  1260  }
  1261  
  1262  func BenchmarkSprintfInt(b *testing.B) {
  1263  	b.RunParallel(func(pb *testing.PB) {
  1264  		p := NewPrinter(language.English)
  1265  		for pb.Next() {
  1266  			p.Sprintf("%d", 5)
  1267  		}
  1268  	})
  1269  }
  1270  
  1271  func BenchmarkSprintfIntInt(b *testing.B) {
  1272  	b.RunParallel(func(pb *testing.PB) {
  1273  		p := NewPrinter(language.English)
  1274  		for pb.Next() {
  1275  			p.Sprintf("%d %d", 5, 6)
  1276  		}
  1277  	})
  1278  }
  1279  
  1280  func BenchmarkSprintfPrefixedInt(b *testing.B) {
  1281  	b.RunParallel(func(pb *testing.PB) {
  1282  		p := NewPrinter(language.English)
  1283  		for pb.Next() {
  1284  			p.Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
  1285  		}
  1286  	})
  1287  }
  1288  
  1289  func BenchmarkSprintfFloat(b *testing.B) {
  1290  	b.RunParallel(func(pb *testing.PB) {
  1291  		p := NewPrinter(language.English)
  1292  		for pb.Next() {
  1293  			p.Sprintf("%g", 5.23184)
  1294  		}
  1295  	})
  1296  }
  1297  
  1298  func BenchmarkSprintfComplex(b *testing.B) {
  1299  	b.RunParallel(func(pb *testing.PB) {
  1300  		p := NewPrinter(language.English)
  1301  		for pb.Next() {
  1302  			p.Sprintf("%f", 5.23184+5.23184i)
  1303  		}
  1304  	})
  1305  }
  1306  
  1307  func BenchmarkSprintfBoolean(b *testing.B) {
  1308  	b.RunParallel(func(pb *testing.PB) {
  1309  		p := NewPrinter(language.English)
  1310  		for pb.Next() {
  1311  			p.Sprintf("%t", true)
  1312  		}
  1313  	})
  1314  }
  1315  
  1316  func BenchmarkSprintfHexString(b *testing.B) {
  1317  	b.RunParallel(func(pb *testing.PB) {
  1318  		p := NewPrinter(language.English)
  1319  		for pb.Next() {
  1320  			p.Sprintf("% #x", "0123456789abcdef")
  1321  		}
  1322  	})
  1323  }
  1324  
  1325  func BenchmarkSprintfHexBytes(b *testing.B) {
  1326  	data := []byte("0123456789abcdef")
  1327  	b.RunParallel(func(pb *testing.PB) {
  1328  		p := NewPrinter(language.English)
  1329  		for pb.Next() {
  1330  			p.Sprintf("% #x", data)
  1331  		}
  1332  	})
  1333  }
  1334  
  1335  func BenchmarkSprintfBytes(b *testing.B) {
  1336  	data := []byte("0123456789abcdef")
  1337  	b.RunParallel(func(pb *testing.PB) {
  1338  		p := NewPrinter(language.English)
  1339  		for pb.Next() {
  1340  			p.Sprintf("%v", data)
  1341  		}
  1342  	})
  1343  }
  1344  
  1345  func BenchmarkSprintfStringer(b *testing.B) {
  1346  	stringer := I(12345)
  1347  	b.RunParallel(func(pb *testing.PB) {
  1348  		p := NewPrinter(language.English)
  1349  		for pb.Next() {
  1350  			p.Sprintf("%v", stringer)
  1351  		}
  1352  	})
  1353  }
  1354  
  1355  func BenchmarkSprintfStructure(b *testing.B) {
  1356  	s := &[]interface{}{SI{12345}, map[int]string{0: "hello"}}
  1357  	b.RunParallel(func(pb *testing.PB) {
  1358  		p := NewPrinter(language.English)
  1359  		for pb.Next() {
  1360  			p.Sprintf("%#v", s)
  1361  		}
  1362  	})
  1363  }
  1364  
  1365  func BenchmarkManyArgs(b *testing.B) {
  1366  	b.RunParallel(func(pb *testing.PB) {
  1367  		var buf bytes.Buffer
  1368  		p := NewPrinter(language.English)
  1369  		for pb.Next() {
  1370  			buf.Reset()
  1371  			p.Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
  1372  		}
  1373  	})
  1374  }
  1375  
  1376  func BenchmarkFprintInt(b *testing.B) {
  1377  	var buf bytes.Buffer
  1378  	p := NewPrinter(language.English)
  1379  	for i := 0; i < b.N; i++ {
  1380  		buf.Reset()
  1381  		p.Fprint(&buf, 123456)
  1382  	}
  1383  }
  1384  
  1385  func BenchmarkFprintfBytes(b *testing.B) {
  1386  	data := []byte(string("0123456789"))
  1387  	var buf bytes.Buffer
  1388  	p := NewPrinter(language.English)
  1389  	for i := 0; i < b.N; i++ {
  1390  		buf.Reset()
  1391  		p.Fprintf(&buf, "%s", data)
  1392  	}
  1393  }
  1394  
  1395  func BenchmarkFprintIntNoAlloc(b *testing.B) {
  1396  	var x interface{} = 123456
  1397  	var buf bytes.Buffer
  1398  	p := NewPrinter(language.English)
  1399  	for i := 0; i < b.N; i++ {
  1400  		buf.Reset()
  1401  		p.Fprint(&buf, x)
  1402  	}
  1403  }
  1404  
  1405  var mallocBuf bytes.Buffer
  1406  var mallocPointer *int // A pointer so we know the interface value won't allocate.
  1407  
  1408  var mallocTest = []struct {
  1409  	count int
  1410  	desc  string
  1411  	fn    func(p *Printer)
  1412  }{
  1413  	{0, `Sprintf("")`, func(p *Printer) { p.Sprintf("") }},
  1414  	{1, `Sprintf("xxx")`, func(p *Printer) { p.Sprintf("xxx") }},
  1415  	{2, `Sprintf("%x")`, func(p *Printer) { p.Sprintf("%x", 7) }},
  1416  	{2, `Sprintf("%s")`, func(p *Printer) { p.Sprintf("%s", "hello") }},
  1417  	{3, `Sprintf("%x %x")`, func(p *Printer) { p.Sprintf("%x %x", 7, 112) }},
  1418  	{2, `Sprintf("%g")`, func(p *Printer) { p.Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1?
  1419  	{1, `Fprintf(buf, "%s")`, func(p *Printer) { mallocBuf.Reset(); p.Fprintf(&mallocBuf, "%s", "hello") }},
  1420  	// If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
  1421  	{0, `Fprintf(buf, "%x %x %x")`, func(p *Printer) {
  1422  		mallocBuf.Reset()
  1423  		p.Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer)
  1424  	}},
  1425  }
  1426  
  1427  var _ bytes.Buffer
  1428  
  1429  func TestCountMallocs(t *testing.T) {
  1430  	switch {
  1431  	case testing.Short():
  1432  		t.Skip("skipping malloc count in short mode")
  1433  	case runtime.GOMAXPROCS(0) > 1:
  1434  		t.Skip("skipping; GOMAXPROCS>1")
  1435  		// TODO: detect race detecter enabled.
  1436  		// case race.Enabled:
  1437  		// 	t.Skip("skipping malloc count under race detector")
  1438  	}
  1439  	p := NewPrinter(language.English)
  1440  	for _, mt := range mallocTest {
  1441  		mallocs := testing.AllocsPerRun(100, func() { mt.fn(p) })
  1442  		if got, max := mallocs, float64(mt.count); got > max {
  1443  			t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
  1444  		}
  1445  	}
  1446  }
  1447  
  1448  type flagPrinter struct{}
  1449  
  1450  func (flagPrinter) Format(f fmt.State, c rune) {
  1451  	s := "%"
  1452  	for i := 0; i < 128; i++ {
  1453  		if f.Flag(i) {
  1454  			s += string(i)
  1455  		}
  1456  	}
  1457  	if w, ok := f.Width(); ok {
  1458  		s += fmt.Sprintf("%d", w)
  1459  	}
  1460  	if p, ok := f.Precision(); ok {
  1461  		s += fmt.Sprintf(".%d", p)
  1462  	}
  1463  	s += string(c)
  1464  	io.WriteString(f, "["+s+"]")
  1465  }
  1466  
  1467  var flagtests = []struct {
  1468  	in  string
  1469  	out string
  1470  }{
  1471  	{"%a", "[%a]"},
  1472  	{"%-a", "[%-a]"},
  1473  	{"%+a", "[%+a]"},
  1474  	{"%#a", "[%#a]"},
  1475  	{"% a", "[% a]"},
  1476  	{"%0a", "[%0a]"},
  1477  	{"%1.2a", "[%1.2a]"},
  1478  	{"%-1.2a", "[%-1.2a]"},
  1479  	{"%+1.2a", "[%+1.2a]"},
  1480  	{"%-+1.2a", "[%+-1.2a]"},
  1481  	{"%-+1.2abc", "[%+-1.2a]bc"},
  1482  	{"%-1.2abc", "[%-1.2a]bc"},
  1483  }
  1484  
  1485  func TestFlagParser(t *testing.T) {
  1486  	var flagprinter flagPrinter
  1487  	for _, tt := range flagtests {
  1488  		s := NewPrinter(language.Und).Sprintf(tt.in, &flagprinter)
  1489  		if s != tt.out {
  1490  			t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
  1491  		}
  1492  	}
  1493  }
  1494  
  1495  func TestStructPrinter(t *testing.T) {
  1496  	type T struct {
  1497  		a string
  1498  		b string
  1499  		c int
  1500  	}
  1501  	var s T
  1502  	s.a = "abc"
  1503  	s.b = "def"
  1504  	s.c = 123
  1505  	var tests = []struct {
  1506  		fmt string
  1507  		out string
  1508  	}{
  1509  		{"%v", "{abc def 123}"},
  1510  		{"%+v", "{a:abc b:def c:123}"},
  1511  		{"%#v", `message.T{a:"abc", b:"def", c:123}`},
  1512  	}
  1513  	p := NewPrinter(language.Und)
  1514  	for _, tt := range tests {
  1515  		out := p.Sprintf(tt.fmt, s)
  1516  		if out != tt.out {
  1517  			t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
  1518  		}
  1519  		// The same but with a pointer.
  1520  		out = p.Sprintf(tt.fmt, &s)
  1521  		if out != "&"+tt.out {
  1522  			t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
  1523  		}
  1524  	}
  1525  }
  1526  
  1527  func TestSlicePrinter(t *testing.T) {
  1528  	p := NewPrinter(language.Und)
  1529  	slice := []int{}
  1530  	s := p.Sprint(slice)
  1531  	if s != "[]" {
  1532  		t.Errorf("empty slice printed as %q not %q", s, "[]")
  1533  	}
  1534  	slice = []int{1, 2, 3}
  1535  	s = p.Sprint(slice)
  1536  	if s != "[1 2 3]" {
  1537  		t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
  1538  	}
  1539  	s = p.Sprint(&slice)
  1540  	if s != "&[1 2 3]" {
  1541  		t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
  1542  	}
  1543  }
  1544  
  1545  // presentInMap checks map printing using substrings so we don't depend on the
  1546  // print order.
  1547  func presentInMap(s string, a []string, t *testing.T) {
  1548  	for i := 0; i < len(a); i++ {
  1549  		loc := strings.Index(s, a[i])
  1550  		if loc < 0 {
  1551  			t.Errorf("map print: expected to find %q in %q", a[i], s)
  1552  		}
  1553  		// make sure the match ends here
  1554  		loc += len(a[i])
  1555  		if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
  1556  			t.Errorf("map print: %q not properly terminated in %q", a[i], s)
  1557  		}
  1558  	}
  1559  }
  1560  
  1561  func TestMapPrinter(t *testing.T) {
  1562  	p := NewPrinter(language.Und)
  1563  	m0 := make(map[int]string)
  1564  	s := p.Sprint(m0)
  1565  	if s != "map[]" {
  1566  		t.Errorf("empty map printed as %q not %q", s, "map[]")
  1567  	}
  1568  	m1 := map[int]string{1: "one", 2: "two", 3: "three"}
  1569  	a := []string{"1:one", "2:two", "3:three"}
  1570  	presentInMap(p.Sprintf("%v", m1), a, t)
  1571  	presentInMap(p.Sprint(m1), a, t)
  1572  	// Pointer to map prints the same but with initial &.
  1573  	if !strings.HasPrefix(p.Sprint(&m1), "&") {
  1574  		t.Errorf("no initial & for address of map")
  1575  	}
  1576  	presentInMap(p.Sprintf("%v", &m1), a, t)
  1577  	presentInMap(p.Sprint(&m1), a, t)
  1578  }
  1579  
  1580  func TestEmptyMap(t *testing.T) {
  1581  	const emptyMapStr = "map[]"
  1582  	var m map[string]int
  1583  	p := NewPrinter(language.Und)
  1584  	s := p.Sprint(m)
  1585  	if s != emptyMapStr {
  1586  		t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
  1587  	}
  1588  	m = make(map[string]int)
  1589  	s = p.Sprint(m)
  1590  	if s != emptyMapStr {
  1591  		t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
  1592  	}
  1593  }
  1594  
  1595  // TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
  1596  // right places, that is, between arg pairs in which neither is a string.
  1597  func TestBlank(t *testing.T) {
  1598  	p := NewPrinter(language.Und)
  1599  	got := p.Sprint("<", 1, ">:", 1, 2, 3, "!")
  1600  	expect := "<1>:1 2 3!"
  1601  	if got != expect {
  1602  		t.Errorf("got %q expected %q", got, expect)
  1603  	}
  1604  }
  1605  
  1606  // TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
  1607  // the right places, that is, between all arg pairs.
  1608  func TestBlankln(t *testing.T) {
  1609  	p := NewPrinter(language.Und)
  1610  	got := p.Sprintln("<", 1, ">:", 1, 2, 3, "!")
  1611  	expect := "< 1 >: 1 2 3 !\n"
  1612  	if got != expect {
  1613  		t.Errorf("got %q expected %q", got, expect)
  1614  	}
  1615  }
  1616  
  1617  // TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
  1618  func TestFormatterPrintln(t *testing.T) {
  1619  	p := NewPrinter(language.Und)
  1620  	f := F(1)
  1621  	expect := "<v=F(1)>\n"
  1622  	s := p.Sprint(f, "\n")
  1623  	if s != expect {
  1624  		t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
  1625  	}
  1626  	s = p.Sprintln(f)
  1627  	if s != expect {
  1628  		t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
  1629  	}
  1630  	s = p.Sprintf("%v\n", f)
  1631  	if s != expect {
  1632  		t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
  1633  	}
  1634  }
  1635  
  1636  func args(a ...interface{}) []interface{} { return a }
  1637  
  1638  var startests = []struct {
  1639  	fmt string
  1640  	in  []interface{}
  1641  	out string
  1642  }{
  1643  	{"%*d", args(4, 42), "  42"},
  1644  	{"%-*d", args(4, 42), "42  "},
  1645  	{"%*d", args(-4, 42), "42  "},
  1646  	{"%-*d", args(-4, 42), "42  "},
  1647  	{"%.*d", args(4, 42), "0,042"},
  1648  	{"%*.*d", args(8, 4, 42), "   0,042"},
  1649  	{"%0*d", args(4, 42), "0,042"},
  1650  	// Some non-int types for width. (Issue 10732).
  1651  	{"%0*d", args(uint(4), 42), "0,042"},
  1652  	{"%0*d", args(uint64(4), 42), "0,042"},
  1653  	{"%0*d", args('\x04', 42), "0,042"},
  1654  	{"%0*d", args(uintptr(4), 42), "0,042"},
  1655  
  1656  	// erroneous
  1657  	{"%*d", args(nil, 42), "%!(BADWIDTH)42"},
  1658  	{"%*d", args(int(1e7), 42), "%!(BADWIDTH)42"},
  1659  	{"%*d", args(int(-1e7), 42), "%!(BADWIDTH)42"},
  1660  	{"%.*d", args(nil, 42), "%!(BADPREC)42"},
  1661  	{"%.*d", args(-1, 42), "%!(BADPREC)42"},
  1662  	{"%.*d", args(int(1e7), 42), "%!(BADPREC)42"},
  1663  	{"%.*d", args(uint(1e7), 42), "%!(BADPREC)42"},
  1664  	{"%.*d", args(uint64(1<<63), 42), "%!(BADPREC)42"},   // Huge negative (-inf).
  1665  	{"%.*d", args(uint64(1<<64-1), 42), "%!(BADPREC)42"}, // Small negative (-1).
  1666  	{"%*d", args(5, "foo"), "%!d(string=  foo)"},
  1667  	{"%*% %d", args(20, 5), "% 5"},
  1668  	{"%*", args(4), "%!(NOVERB)"},
  1669  }
  1670  
  1671  func TestWidthAndPrecision(t *testing.T) {
  1672  	p := NewPrinter(language.Und)
  1673  	for i, tt := range startests {
  1674  		t.Run(fmt.Sprint(tt.fmt, tt.in), func(t *testing.T) {
  1675  			s := p.Sprintf(tt.fmt, tt.in...)
  1676  			if s != tt.out {
  1677  				t.Errorf("#%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
  1678  			}
  1679  		})
  1680  	}
  1681  }
  1682  
  1683  // PanicS is a type that panics in String.
  1684  type PanicS struct {
  1685  	message interface{}
  1686  }
  1687  
  1688  // Value receiver.
  1689  func (p PanicS) String() string {
  1690  	panic(p.message)
  1691  }
  1692  
  1693  // PanicGo is a type that panics in GoString.
  1694  type PanicGo struct {
  1695  	message interface{}
  1696  }
  1697  
  1698  // Value receiver.
  1699  func (p PanicGo) GoString() string {
  1700  	panic(p.message)
  1701  }
  1702  
  1703  // PanicF is a type that panics in Format.
  1704  type PanicF struct {
  1705  	message interface{}
  1706  }
  1707  
  1708  // Value receiver.
  1709  func (p PanicF) Format(f fmt.State, c rune) {
  1710  	panic(p.message)
  1711  }
  1712  
  1713  var panictests = []struct {
  1714  	desc string
  1715  	fmt  string
  1716  	in   interface{}
  1717  	out  string
  1718  }{
  1719  	// String
  1720  	{"String", "%s", (*PanicS)(nil), "<nil>"}, // nil pointer special case
  1721  	{"String", "%s", PanicS{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
  1722  	{"String", "%s", PanicS{3}, "%!s(PANIC=3)"},
  1723  	// GoString
  1724  	{"GoString", "%#v", (*PanicGo)(nil), "<nil>"}, // nil pointer special case
  1725  	{"GoString", "%#v", PanicGo{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"},
  1726  	{"GoString", "%#v", PanicGo{3}, "%!v(PANIC=3)"},
  1727  	// Issue 18282. catchPanic should not clear fmtFlags permanently.
  1728  	{"Issue 18282", "%#v", []interface{}{PanicGo{3}, PanicGo{3}}, "[]interface {}{%!v(PANIC=3), %!v(PANIC=3)}"},
  1729  	// Format
  1730  	{"Format", "%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
  1731  	{"Format", "%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
  1732  	{"Format", "%s", PanicF{3}, "%!s(PANIC=3)"},
  1733  }
  1734  
  1735  func TestPanics(t *testing.T) {
  1736  	p := NewPrinter(language.Und)
  1737  	for i, tt := range panictests {
  1738  		t.Run(fmt.Sprint(tt.desc, "/", tt.fmt, "/", tt.in), func(t *testing.T) {
  1739  			s := p.Sprintf(tt.fmt, tt.in)
  1740  			if s != tt.out {
  1741  				t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
  1742  			}
  1743  		})
  1744  	}
  1745  }
  1746  
  1747  // recurCount tests that erroneous String routine doesn't cause fatal recursion.
  1748  var recurCount = 0
  1749  
  1750  type Recur struct {
  1751  	i      int
  1752  	failed *bool
  1753  }
  1754  
  1755  func (r *Recur) String() string {
  1756  	p := NewPrinter(language.Und)
  1757  	if recurCount++; recurCount > 10 {
  1758  		*r.failed = true
  1759  		return "FAIL"
  1760  	}
  1761  	// This will call badVerb. Before the fix, that would cause us to recur into
  1762  	// this routine to print %!p(value). Now we don't call the user's method
  1763  	// during an error.
  1764  	return p.Sprintf("recur@%p value: %d", r, r.i)
  1765  }
  1766  
  1767  func TestBadVerbRecursion(t *testing.T) {
  1768  	p := NewPrinter(language.Und)
  1769  	failed := false
  1770  	r := &Recur{3, &failed}
  1771  	p.Sprintf("recur@%p value: %d\n", &r, r.i)
  1772  	if failed {
  1773  		t.Error("fail with pointer")
  1774  	}
  1775  	failed = false
  1776  	r = &Recur{4, &failed}
  1777  	p.Sprintf("recur@%p, value: %d\n", r, r.i)
  1778  	if failed {
  1779  		t.Error("fail with value")
  1780  	}
  1781  }
  1782  
  1783  func TestNilDoesNotBecomeTyped(t *testing.T) {
  1784  	p := NewPrinter(language.Und)
  1785  	type A struct{}
  1786  	type B struct{}
  1787  	var a *A = nil
  1788  	var b B = B{}
  1789  
  1790  	// indirect the Sprintf call through this noVetWarn variable to avoid
  1791  	// "go test" failing vet checks in Go 1.10+.
  1792  	noVetWarn := p.Sprintf
  1793  	got := noVetWarn("%s %s %s %s %s", nil, a, nil, b, nil)
  1794  
  1795  	const expect = "%!s(<nil>) %!s(*message.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
  1796  	if got != expect {
  1797  		t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
  1798  	}
  1799  }
  1800  
  1801  var formatterFlagTests = []struct {
  1802  	in  string
  1803  	val interface{}
  1804  	out string
  1805  }{
  1806  	// scalar values with the (unused by fmt) 'a' verb.
  1807  	{"%a", flagPrinter{}, "[%a]"},
  1808  	{"%-a", flagPrinter{}, "[%-a]"},
  1809  	{"%+a", flagPrinter{}, "[%+a]"},
  1810  	{"%#a", flagPrinter{}, "[%#a]"},
  1811  	{"% a", flagPrinter{}, "[% a]"},
  1812  	{"%0a", flagPrinter{}, "[%0a]"},
  1813  	{"%1.2a", flagPrinter{}, "[%1.2a]"},
  1814  	{"%-1.2a", flagPrinter{}, "[%-1.2a]"},
  1815  	{"%+1.2a", flagPrinter{}, "[%+1.2a]"},
  1816  	{"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
  1817  	{"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
  1818  	{"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
  1819  
  1820  	// composite values with the 'a' verb
  1821  	{"%a", [1]flagPrinter{}, "[[%a]]"},
  1822  	{"%-a", [1]flagPrinter{}, "[[%-a]]"},
  1823  	{"%+a", [1]flagPrinter{}, "[[%+a]]"},
  1824  	{"%#a", [1]flagPrinter{}, "[[%#a]]"},
  1825  	{"% a", [1]flagPrinter{}, "[[% a]]"},
  1826  	{"%0a", [1]flagPrinter{}, "[[%0a]]"},
  1827  	{"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
  1828  	{"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
  1829  	{"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
  1830  	{"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
  1831  	{"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
  1832  	{"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
  1833  
  1834  	// simple values with the 'v' verb
  1835  	{"%v", flagPrinter{}, "[%v]"},
  1836  	{"%-v", flagPrinter{}, "[%-v]"},
  1837  	{"%+v", flagPrinter{}, "[%+v]"},
  1838  	{"%#v", flagPrinter{}, "[%#v]"},
  1839  	{"% v", flagPrinter{}, "[% v]"},
  1840  	{"%0v", flagPrinter{}, "[%0v]"},
  1841  	{"%1.2v", flagPrinter{}, "[%1.2v]"},
  1842  	{"%-1.2v", flagPrinter{}, "[%-1.2v]"},
  1843  	{"%+1.2v", flagPrinter{}, "[%+1.2v]"},
  1844  	{"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
  1845  	{"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
  1846  	{"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
  1847  
  1848  	// composite values with the 'v' verb.
  1849  	{"%v", [1]flagPrinter{}, "[[%v]]"},
  1850  	{"%-v", [1]flagPrinter{}, "[[%-v]]"},
  1851  	{"%+v", [1]flagPrinter{}, "[[%+v]]"},
  1852  	{"%#v", [1]flagPrinter{}, "[1]message.flagPrinter{[%#v]}"},
  1853  	{"% v", [1]flagPrinter{}, "[[% v]]"},
  1854  	{"%0v", [1]flagPrinter{}, "[[%0v]]"},
  1855  	{"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
  1856  	{"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
  1857  	{"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
  1858  	{"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
  1859  	{"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
  1860  	{"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
  1861  }
  1862  
  1863  func TestFormatterFlags(t *testing.T) {
  1864  	p := NewPrinter(language.Und)
  1865  	for _, tt := range formatterFlagTests {
  1866  		s := p.Sprintf(tt.in, tt.val)
  1867  		if s != tt.out {
  1868  			t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out)
  1869  		}
  1870  	}
  1871  }