github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/fmt/scan_test.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fmt_test
     6  
     7  import (
     8  	"bufio"
     9  	"bytes"
    10  	"errors"
    11  	. "fmt"
    12  	"io"
    13  	"math"
    14  	"reflect"
    15  	"regexp"
    16  	"strings"
    17  	"testing"
    18  	"unicode/utf8"
    19  )
    20  
    21  type ScanTest struct {
    22  	text string
    23  	in   interface{}
    24  	out  interface{}
    25  }
    26  
    27  type ScanfTest struct {
    28  	format string
    29  	text   string
    30  	in     interface{}
    31  	out    interface{}
    32  }
    33  
    34  type ScanfMultiTest struct {
    35  	format string
    36  	text   string
    37  	in     []interface{}
    38  	out    []interface{}
    39  	err    string
    40  }
    41  
    42  var (
    43  	boolVal              bool
    44  	intVal               int
    45  	int8Val              int8
    46  	int16Val             int16
    47  	int32Val             int32
    48  	int64Val             int64
    49  	uintVal              uint
    50  	uint8Val             uint8
    51  	uint16Val            uint16
    52  	uint32Val            uint32
    53  	uint64Val            uint64
    54  	float32Val           float32
    55  	float64Val           float64
    56  	stringVal            string
    57  	bytesVal             []byte
    58  	runeVal              rune
    59  	complex64Val         complex64
    60  	complex128Val        complex128
    61  	renamedBoolVal       renamedBool
    62  	renamedIntVal        renamedInt
    63  	renamedInt8Val       renamedInt8
    64  	renamedInt16Val      renamedInt16
    65  	renamedInt32Val      renamedInt32
    66  	renamedInt64Val      renamedInt64
    67  	renamedUintVal       renamedUint
    68  	renamedUint8Val      renamedUint8
    69  	renamedUint16Val     renamedUint16
    70  	renamedUint32Val     renamedUint32
    71  	renamedUint64Val     renamedUint64
    72  	renamedUintptrVal    renamedUintptr
    73  	renamedStringVal     renamedString
    74  	renamedBytesVal      renamedBytes
    75  	renamedFloat32Val    renamedFloat32
    76  	renamedFloat64Val    renamedFloat64
    77  	renamedComplex64Val  renamedComplex64
    78  	renamedComplex128Val renamedComplex128
    79  )
    80  
    81  type FloatTest struct {
    82  	text string
    83  	in   float64
    84  	out  float64
    85  }
    86  
    87  // Xs accepts any non-empty run of the verb character
    88  type Xs string
    89  
    90  func (x *Xs) Scan(state ScanState, verb rune) error {
    91  	tok, err := state.Token(true, func(r rune) bool { return r == verb })
    92  	if err != nil {
    93  		return err
    94  	}
    95  	s := string(tok)
    96  	if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) {
    97  		return errors.New("syntax error for xs")
    98  	}
    99  	*x = Xs(s)
   100  	return nil
   101  }
   102  
   103  var xVal Xs
   104  
   105  // IntString accepts an integer followed immediately by a string.
   106  // It tests the embedding of a scan within a scan.
   107  type IntString struct {
   108  	i int
   109  	s string
   110  }
   111  
   112  func (s *IntString) Scan(state ScanState, verb rune) error {
   113  	if _, err := Fscan(state, &s.i); err != nil {
   114  		return err
   115  	}
   116  
   117  	tok, err := state.Token(true, nil)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	s.s = string(tok)
   122  	return nil
   123  }
   124  
   125  var intStringVal IntString
   126  
   127  // myStringReader implements Read but not ReadRune, allowing us to test our readRune wrapper
   128  // type that creates something that can read runes given only Read().
   129  type myStringReader struct {
   130  	r *strings.Reader
   131  }
   132  
   133  func (s *myStringReader) Read(p []byte) (n int, err error) {
   134  	return s.r.Read(p)
   135  }
   136  
   137  func newReader(s string) *myStringReader {
   138  	return &myStringReader{strings.NewReader(s)}
   139  }
   140  
   141  var scanTests = []ScanTest{
   142  	// Basic types
   143  	{"T\n", &boolVal, true},  // boolean test vals toggle to be sure they are written
   144  	{"F\n", &boolVal, false}, // restored to zero value
   145  	{"21\n", &intVal, 21},
   146  	{"0\n", &intVal, 0},
   147  	{"000\n", &intVal, 0},
   148  	{"0x10\n", &intVal, 0x10},
   149  	{"-0x10\n", &intVal, -0x10},
   150  	{"0377\n", &intVal, 0377},
   151  	{"-0377\n", &intVal, -0377},
   152  	{"0\n", &uintVal, uint(0)},
   153  	{"000\n", &uintVal, uint(0)},
   154  	{"0x10\n", &uintVal, uint(0x10)},
   155  	{"0377\n", &uintVal, uint(0377)},
   156  	{"22\n", &int8Val, int8(22)},
   157  	{"23\n", &int16Val, int16(23)},
   158  	{"24\n", &int32Val, int32(24)},
   159  	{"25\n", &int64Val, int64(25)},
   160  	{"127\n", &int8Val, int8(127)},
   161  	{"-21\n", &intVal, -21},
   162  	{"-22\n", &int8Val, int8(-22)},
   163  	{"-23\n", &int16Val, int16(-23)},
   164  	{"-24\n", &int32Val, int32(-24)},
   165  	{"-25\n", &int64Val, int64(-25)},
   166  	{"-128\n", &int8Val, int8(-128)},
   167  	{"+21\n", &intVal, +21},
   168  	{"+22\n", &int8Val, int8(+22)},
   169  	{"+23\n", &int16Val, int16(+23)},
   170  	{"+24\n", &int32Val, int32(+24)},
   171  	{"+25\n", &int64Val, int64(+25)},
   172  	{"+127\n", &int8Val, int8(+127)},
   173  	{"26\n", &uintVal, uint(26)},
   174  	{"27\n", &uint8Val, uint8(27)},
   175  	{"28\n", &uint16Val, uint16(28)},
   176  	{"29\n", &uint32Val, uint32(29)},
   177  	{"30\n", &uint64Val, uint64(30)},
   178  	{"255\n", &uint8Val, uint8(255)},
   179  	{"32767\n", &int16Val, int16(32767)},
   180  	{"2.3\n", &float64Val, 2.3},
   181  	{"2.3e1\n", &float32Val, float32(2.3e1)},
   182  	{"2.3e2\n", &float64Val, 2.3e2},
   183  	{"2.3p2\n", &float64Val, 2.3 * 4},
   184  	{"2.3p+2\n", &float64Val, 2.3 * 4},
   185  	{"2.3p+66\n", &float64Val, 2.3 * (1 << 32) * (1 << 32) * 4},
   186  	{"2.3p-66\n", &float64Val, 2.3 / ((1 << 32) * (1 << 32) * 4)},
   187  	{"2.35\n", &stringVal, "2.35"},
   188  	{"2345678\n", &bytesVal, []byte("2345678")},
   189  	{"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i},
   190  	{"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)},
   191  	{"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)},
   192  	{"hello\n", &stringVal, "hello"},
   193  
   194  	// Carriage-return followed by newline. (We treat \r\n as \n always.)
   195  	{"hello\r\n", &stringVal, "hello"},
   196  	{"27\r\n", &uint8Val, uint8(27)},
   197  
   198  	// Renamed types
   199  	{"true\n", &renamedBoolVal, renamedBool(true)},
   200  	{"F\n", &renamedBoolVal, renamedBool(false)},
   201  	{"101\n", &renamedIntVal, renamedInt(101)},
   202  	{"102\n", &renamedIntVal, renamedInt(102)},
   203  	{"103\n", &renamedUintVal, renamedUint(103)},
   204  	{"104\n", &renamedUintVal, renamedUint(104)},
   205  	{"105\n", &renamedInt8Val, renamedInt8(105)},
   206  	{"106\n", &renamedInt16Val, renamedInt16(106)},
   207  	{"107\n", &renamedInt32Val, renamedInt32(107)},
   208  	{"108\n", &renamedInt64Val, renamedInt64(108)},
   209  	{"109\n", &renamedUint8Val, renamedUint8(109)},
   210  	{"110\n", &renamedUint16Val, renamedUint16(110)},
   211  	{"111\n", &renamedUint32Val, renamedUint32(111)},
   212  	{"112\n", &renamedUint64Val, renamedUint64(112)},
   213  	{"113\n", &renamedUintptrVal, renamedUintptr(113)},
   214  	{"114\n", &renamedStringVal, renamedString("114")},
   215  	{"115\n", &renamedBytesVal, renamedBytes([]byte("115"))},
   216  
   217  	// Custom scanners.
   218  	{"  vvv ", &xVal, Xs("vvv")},
   219  	{" 1234hello", &intStringVal, IntString{1234, "hello"}},
   220  
   221  	// Fixed bugs
   222  	{"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow
   223  }
   224  
   225  var scanfTests = []ScanfTest{
   226  	{"%v", "TRUE\n", &boolVal, true},
   227  	{"%t", "false\n", &boolVal, false},
   228  	{"%v", "-71\n", &intVal, -71},
   229  	{"%v", "0377\n", &intVal, 0377},
   230  	{"%v", "0x44\n", &intVal, 0x44},
   231  	{"%d", "72\n", &intVal, 72},
   232  	{"%c", "a\n", &runeVal, 'a'},
   233  	{"%c", "\u5072\n", &runeVal, '\u5072'},
   234  	{"%c", "\u1234\n", &runeVal, '\u1234'},
   235  	{"%d", "73\n", &int8Val, int8(73)},
   236  	{"%d", "+74\n", &int16Val, int16(74)},
   237  	{"%d", "75\n", &int32Val, int32(75)},
   238  	{"%d", "76\n", &int64Val, int64(76)},
   239  	{"%b", "1001001\n", &intVal, 73},
   240  	{"%o", "075\n", &intVal, 075},
   241  	{"%x", "a75\n", &intVal, 0xa75},
   242  	{"%v", "71\n", &uintVal, uint(71)},
   243  	{"%d", "72\n", &uintVal, uint(72)},
   244  	{"%d", "73\n", &uint8Val, uint8(73)},
   245  	{"%d", "74\n", &uint16Val, uint16(74)},
   246  	{"%d", "75\n", &uint32Val, uint32(75)},
   247  	{"%d", "76\n", &uint64Val, uint64(76)},
   248  	{"%b", "1001001\n", &uintVal, uint(73)},
   249  	{"%o", "075\n", &uintVal, uint(075)},
   250  	{"%x", "a75\n", &uintVal, uint(0xa75)},
   251  	{"%x", "A75\n", &uintVal, uint(0xa75)},
   252  	{"%U", "U+1234\n", &intVal, int(0x1234)},
   253  	{"%U", "U+4567\n", &uintVal, uint(0x4567)},
   254  
   255  	// Strings
   256  	{"%s", "using-%s\n", &stringVal, "using-%s"},
   257  	{"%x", "7573696e672d2578\n", &stringVal, "using-%x"},
   258  	{"%X", "7573696E672D2558\n", &stringVal, "using-%X"},
   259  	{"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal, "quoted\twith\\doubles"},
   260  	{"%q", "`quoted with backs`\n", &stringVal, "quoted with backs"},
   261  
   262  	// Byte slices
   263  	{"%s", "bytes-%s\n", &bytesVal, []byte("bytes-%s")},
   264  	{"%x", "62797465732d2578\n", &bytesVal, []byte("bytes-%x")},
   265  	{"%X", "62797465732D2558\n", &bytesVal, []byte("bytes-%X")},
   266  	{"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal, []byte("bytes\rwith\vdoubles")},
   267  	{"%q", "`bytes with backs`\n", &bytesVal, []byte("bytes with backs")},
   268  
   269  	// Renamed types
   270  	{"%v\n", "true\n", &renamedBoolVal, renamedBool(true)},
   271  	{"%t\n", "F\n", &renamedBoolVal, renamedBool(false)},
   272  	{"%v", "101\n", &renamedIntVal, renamedInt(101)},
   273  	{"%c", "\u0101\n", &renamedIntVal, renamedInt('\u0101')},
   274  	{"%o", "0146\n", &renamedIntVal, renamedInt(102)},
   275  	{"%v", "103\n", &renamedUintVal, renamedUint(103)},
   276  	{"%d", "104\n", &renamedUintVal, renamedUint(104)},
   277  	{"%d", "105\n", &renamedInt8Val, renamedInt8(105)},
   278  	{"%d", "106\n", &renamedInt16Val, renamedInt16(106)},
   279  	{"%d", "107\n", &renamedInt32Val, renamedInt32(107)},
   280  	{"%d", "108\n", &renamedInt64Val, renamedInt64(108)},
   281  	{"%x", "6D\n", &renamedUint8Val, renamedUint8(109)},
   282  	{"%o", "0156\n", &renamedUint16Val, renamedUint16(110)},
   283  	{"%d", "111\n", &renamedUint32Val, renamedUint32(111)},
   284  	{"%d", "112\n", &renamedUint64Val, renamedUint64(112)},
   285  	{"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)},
   286  	{"%s", "114\n", &renamedStringVal, renamedString("114")},
   287  	{"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))},
   288  	{"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)},
   289  	{"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)},
   290  	{"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)},
   291  	{"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)},
   292  
   293  	// Interesting formats
   294  	{"here is\tthe value:%d", "here is   the\tvalue:118\n", &intVal, 118},
   295  	{"%% %%:%d", "% %:119\n", &intVal, 119},
   296  	{"%d%%", "42%", &intVal, 42}, // %% at end of string.
   297  
   298  	// Corner cases
   299  	{"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)},
   300  
   301  	// Custom scanner.
   302  	{"%s", "  sss ", &xVal, Xs("sss")},
   303  	{"%2s", "sssss", &xVal, Xs("ss")},
   304  
   305  	// Fixed bugs
   306  	{"%d\n", "27\n", &intVal, 27},      // ok
   307  	{"%d\n", "28 \n", &intVal, 28},     // was: "unexpected newline"
   308  	{"%v", "0", &intVal, 0},            // was: "EOF"; 0 was taken as base prefix and not counted.
   309  	{"%v", "0", &uintVal, uint(0)},     // was: "EOF"; 0 was taken as base prefix and not counted.
   310  	{"%c", " ", &uintVal, uint(' ')},   // %c must accept a blank.
   311  	{"%c", "\t", &uintVal, uint('\t')}, // %c must accept any space.
   312  	{"%c", "\n", &uintVal, uint('\n')}, // %c must accept any space.
   313  }
   314  
   315  var overflowTests = []ScanTest{
   316  	{"128", &int8Val, 0},
   317  	{"32768", &int16Val, 0},
   318  	{"-129", &int8Val, 0},
   319  	{"-32769", &int16Val, 0},
   320  	{"256", &uint8Val, 0},
   321  	{"65536", &uint16Val, 0},
   322  	{"1e100", &float32Val, 0},
   323  	{"1e500", &float64Val, 0},
   324  	{"(1e100+0i)", &complex64Val, 0},
   325  	{"(1+1e100i)", &complex64Val, 0},
   326  	{"(1-1e500i)", &complex128Val, 0},
   327  }
   328  
   329  var truth bool
   330  var i, j, k int
   331  var f float64
   332  var s, t string
   333  var c complex128
   334  var x, y Xs
   335  var z IntString
   336  var r1, r2, r3 rune
   337  
   338  var multiTests = []ScanfMultiTest{
   339  	{"", "", []interface{}{}, []interface{}{}, ""},
   340  	{"%d", "23", args(&i), args(23), ""},
   341  	{"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""},
   342  	{"%2d%3d", "44555", args(&i, &j), args(44, 555), ""},
   343  	{"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""},
   344  	{"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""},
   345  	{"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
   346  	{"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
   347  	{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
   348  	{"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
   349  	{"%5s%d", " 1234567 ", args(&s, &i), args("12345", 67), ""},
   350  	{"%5s%d", " 12 34 567 ", args(&s, &i), args("12", 34), ""},
   351  
   352  	// Custom scanners.
   353  	{"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
   354  	{"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
   355  
   356  	// Errors
   357  	{"%t", "23 18", args(&i), nil, "bad verb"},
   358  	{"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
   359  	{"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
   360  	{"%c", "\u0100", args(&int8Val), nil, "overflow"},
   361  	{"X%d", "10X", args(&intVal), nil, "input does not match format"},
   362  	{"%d%", "42%", args(&intVal), args(42), "missing verb: % at end of format string"},
   363  	{"%d% ", "42%", args(&intVal), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct.
   364  
   365  	// Bad UTF-8: should see every byte.
   366  	{"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
   367  
   368  	// Fixed bugs
   369  	{"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""},
   370  }
   371  
   372  func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {
   373  	for _, test := range scanTests {
   374  		var r io.Reader
   375  		if name == "StringReader" {
   376  			r = strings.NewReader(test.text)
   377  		} else {
   378  			r = newReader(test.text)
   379  		}
   380  		n, err := scan(r, test.in)
   381  		if err != nil {
   382  			m := ""
   383  			if n > 0 {
   384  				m = Sprintf(" (%d fields ok)", n)
   385  			}
   386  			t.Errorf("%s got error scanning %q: %s%s", name, test.text, err, m)
   387  			continue
   388  		}
   389  		if n != 1 {
   390  			t.Errorf("%s count error on entry %q: got %d", name, test.text, n)
   391  			continue
   392  		}
   393  		// The incoming value may be a pointer
   394  		v := reflect.ValueOf(test.in)
   395  		if p := v; p.Kind() == reflect.Ptr {
   396  			v = p.Elem()
   397  		}
   398  		val := v.Interface()
   399  		if !reflect.DeepEqual(val, test.out) {
   400  			t.Errorf("%s scanning %q: expected %#v got %#v, type %T", name, test.text, test.out, val, val)
   401  		}
   402  	}
   403  }
   404  
   405  func TestScan(t *testing.T) {
   406  	testScan("StringReader", t, Fscan)
   407  }
   408  
   409  func TestMyReaderScan(t *testing.T) {
   410  	testScan("myStringReader", t, Fscan)
   411  }
   412  
   413  func TestScanln(t *testing.T) {
   414  	testScan("StringReader", t, Fscanln)
   415  }
   416  
   417  func TestMyReaderScanln(t *testing.T) {
   418  	testScan("myStringReader", t, Fscanln)
   419  }
   420  
   421  func TestScanf(t *testing.T) {
   422  	for _, test := range scanfTests {
   423  		n, err := Sscanf(test.text, test.format, test.in)
   424  		if err != nil {
   425  			t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err)
   426  			continue
   427  		}
   428  		if n != 1 {
   429  			t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n)
   430  			continue
   431  		}
   432  		// The incoming value may be a pointer
   433  		v := reflect.ValueOf(test.in)
   434  		if p := v; p.Kind() == reflect.Ptr {
   435  			v = p.Elem()
   436  		}
   437  		val := v.Interface()
   438  		if !reflect.DeepEqual(val, test.out) {
   439  			t.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test.format, test.text, test.out, val, val)
   440  		}
   441  	}
   442  }
   443  
   444  func TestScanOverflow(t *testing.T) {
   445  	// different machines and different types report errors with different strings.
   446  	re := regexp.MustCompile("overflow|too large|out of range|not representable")
   447  	for _, test := range overflowTests {
   448  		_, err := Sscan(test.text, test.in)
   449  		if err == nil {
   450  			t.Errorf("expected overflow scanning %q", test.text)
   451  			continue
   452  		}
   453  		if !re.MatchString(err.Error()) {
   454  			t.Errorf("expected overflow error scanning %q: %s", test.text, err)
   455  		}
   456  	}
   457  }
   458  
   459  func verifyNaN(str string, t *testing.T) {
   460  	var f float64
   461  	var f32 float32
   462  	var f64 float64
   463  	text := str + " " + str + " " + str
   464  	n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
   465  	if err != nil {
   466  		t.Errorf("got error scanning %q: %s", text, err)
   467  	}
   468  	if n != 3 {
   469  		t.Errorf("count error scanning %q: got %d", text, n)
   470  	}
   471  	if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) {
   472  		t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64)
   473  	}
   474  }
   475  
   476  func TestNaN(t *testing.T) {
   477  	for _, s := range []string{"nan", "NAN", "NaN"} {
   478  		verifyNaN(s, t)
   479  	}
   480  }
   481  
   482  func verifyInf(str string, t *testing.T) {
   483  	var f float64
   484  	var f32 float32
   485  	var f64 float64
   486  	text := str + " " + str + " " + str
   487  	n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
   488  	if err != nil {
   489  		t.Errorf("got error scanning %q: %s", text, err)
   490  	}
   491  	if n != 3 {
   492  		t.Errorf("count error scanning %q: got %d", text, n)
   493  	}
   494  	sign := 1
   495  	if str[0] == '-' {
   496  		sign = -1
   497  	}
   498  	if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) {
   499  		t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64)
   500  	}
   501  }
   502  
   503  func TestInf(t *testing.T) {
   504  	for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
   505  		verifyInf(s, t)
   506  	}
   507  }
   508  
   509  func testScanfMulti(name string, t *testing.T) {
   510  	sliceType := reflect.TypeOf(make([]interface{}, 1))
   511  	for _, test := range multiTests {
   512  		var r io.Reader
   513  		if name == "StringReader" {
   514  			r = strings.NewReader(test.text)
   515  		} else {
   516  			r = newReader(test.text)
   517  		}
   518  		n, err := Fscanf(r, test.format, test.in...)
   519  		if err != nil {
   520  			if test.err == "" {
   521  				t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err)
   522  			} else if strings.Index(err.Error(), test.err) < 0 {
   523  				t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
   524  			}
   525  			continue
   526  		}
   527  		if test.err != "" {
   528  			t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
   529  		}
   530  		if n != len(test.out) {
   531  			t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n)
   532  			continue
   533  		}
   534  		// Convert the slice of pointers into a slice of values
   535  		resultVal := reflect.MakeSlice(sliceType, n, n)
   536  		for i := 0; i < n; i++ {
   537  			v := reflect.ValueOf(test.in[i]).Elem()
   538  			resultVal.Index(i).Set(v)
   539  		}
   540  		result := resultVal.Interface()
   541  		if !reflect.DeepEqual(result, test.out) {
   542  			t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result)
   543  		}
   544  	}
   545  }
   546  
   547  func TestScanfMulti(t *testing.T) {
   548  	testScanfMulti("StringReader", t)
   549  }
   550  
   551  func TestMyReaderScanfMulti(t *testing.T) {
   552  	testScanfMulti("myStringReader", t)
   553  }
   554  
   555  func TestScanMultiple(t *testing.T) {
   556  	var a int
   557  	var s string
   558  	n, err := Sscan("123abc", &a, &s)
   559  	if n != 2 {
   560  		t.Errorf("Sscan count error: expected 2: got %d", n)
   561  	}
   562  	if err != nil {
   563  		t.Errorf("Sscan expected no error; got %s", err)
   564  	}
   565  	if a != 123 || s != "abc" {
   566  		t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
   567  	}
   568  	n, err = Sscan("asdf", &s, &a)
   569  	if n != 1 {
   570  		t.Errorf("Sscan count error: expected 1: got %d", n)
   571  	}
   572  	if err == nil {
   573  		t.Errorf("Sscan expected error; got none: %s", err)
   574  	}
   575  	if s != "asdf" {
   576  		t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
   577  	}
   578  }
   579  
   580  // Empty strings are not valid input when scanning a string.
   581  func TestScanEmpty(t *testing.T) {
   582  	var s1, s2 string
   583  	n, err := Sscan("abc", &s1, &s2)
   584  	if n != 1 {
   585  		t.Errorf("Sscan count error: expected 1: got %d", n)
   586  	}
   587  	if err == nil {
   588  		t.Error("Sscan <one item> expected error; got none")
   589  	}
   590  	if s1 != "abc" {
   591  		t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
   592  	}
   593  	n, err = Sscan("", &s1, &s2)
   594  	if n != 0 {
   595  		t.Errorf("Sscan count error: expected 0: got %d", n)
   596  	}
   597  	if err == nil {
   598  		t.Error("Sscan <empty> expected error; got none")
   599  	}
   600  	// Quoted empty string is OK.
   601  	n, err = Sscanf(`""`, "%q", &s1)
   602  	if n != 1 {
   603  		t.Errorf("Sscanf count error: expected 1: got %d", n)
   604  	}
   605  	if err != nil {
   606  		t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err)
   607  	}
   608  }
   609  
   610  func TestScanNotPointer(t *testing.T) {
   611  	r := strings.NewReader("1")
   612  	var a int
   613  	_, err := Fscan(r, a)
   614  	if err == nil {
   615  		t.Error("expected error scanning non-pointer")
   616  	} else if strings.Index(err.Error(), "pointer") < 0 {
   617  		t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
   618  	}
   619  }
   620  
   621  func TestScanlnNoNewline(t *testing.T) {
   622  	var a int
   623  	_, err := Sscanln("1 x\n", &a)
   624  	if err == nil {
   625  		t.Error("expected error scanning string missing newline")
   626  	} else if strings.Index(err.Error(), "newline") < 0 {
   627  		t.Errorf("expected newline error scanning string missing newline, got: %s", err)
   628  	}
   629  }
   630  
   631  func TestScanlnWithMiddleNewline(t *testing.T) {
   632  	r := strings.NewReader("123\n456\n")
   633  	var a, b int
   634  	_, err := Fscanln(r, &a, &b)
   635  	if err == nil {
   636  		t.Error("expected error scanning string with extra newline")
   637  	} else if strings.Index(err.Error(), "newline") < 0 {
   638  		t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
   639  	}
   640  }
   641  
   642  // eofCounter is a special Reader that counts reads at end of file.
   643  type eofCounter struct {
   644  	reader   *strings.Reader
   645  	eofCount int
   646  }
   647  
   648  func (ec *eofCounter) Read(b []byte) (n int, err error) {
   649  	n, err = ec.reader.Read(b)
   650  	if n == 0 {
   651  		ec.eofCount++
   652  	}
   653  	return
   654  }
   655  
   656  // TestEOF verifies that when we scan, we see at most EOF once per call to a
   657  // Scan function, and then only when it's really an EOF.
   658  func TestEOF(t *testing.T) {
   659  	ec := &eofCounter{strings.NewReader("123\n"), 0}
   660  	var a int
   661  	n, err := Fscanln(ec, &a)
   662  	if err != nil {
   663  		t.Error("unexpected error", err)
   664  	}
   665  	if n != 1 {
   666  		t.Error("expected to scan one item, got", n)
   667  	}
   668  	if ec.eofCount != 0 {
   669  		t.Error("expected zero EOFs", ec.eofCount)
   670  		ec.eofCount = 0 // reset for next test
   671  	}
   672  	n, err = Fscanln(ec, &a)
   673  	if err == nil {
   674  		t.Error("expected error scanning empty string")
   675  	}
   676  	if n != 0 {
   677  		t.Error("expected to scan zero items, got", n)
   678  	}
   679  	if ec.eofCount != 1 {
   680  		t.Error("expected one EOF, got", ec.eofCount)
   681  	}
   682  }
   683  
   684  // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
   685  // This was a buglet: we used to get "expected integer".
   686  func TestEOFAtEndOfInput(t *testing.T) {
   687  	var i, j int
   688  	n, err := Sscanf("23", "%d %d", &i, &j)
   689  	if n != 1 || i != 23 {
   690  		t.Errorf("Sscanf expected one value of 23; got %d %d", n, i)
   691  	}
   692  	if err != io.EOF {
   693  		t.Errorf("Sscanf expected EOF; got %q", err)
   694  	}
   695  	n, err = Sscan("234", &i, &j)
   696  	if n != 1 || i != 234 {
   697  		t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
   698  	}
   699  	if err != io.EOF {
   700  		t.Errorf("Sscan expected EOF; got %q", err)
   701  	}
   702  	// Trailing space is tougher.
   703  	n, err = Sscan("234 ", &i, &j)
   704  	if n != 1 || i != 234 {
   705  		t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
   706  	}
   707  	if err != io.EOF {
   708  		t.Errorf("Sscan expected EOF; got %q", err)
   709  	}
   710  }
   711  
   712  var eofTests = []struct {
   713  	format string
   714  	v      interface{}
   715  }{
   716  	{"%s", &stringVal},
   717  	{"%q", &stringVal},
   718  	{"%x", &stringVal},
   719  	{"%v", &stringVal},
   720  	{"%v", &bytesVal},
   721  	{"%v", &intVal},
   722  	{"%v", &uintVal},
   723  	{"%v", &boolVal},
   724  	{"%v", &float32Val},
   725  	{"%v", &complex64Val},
   726  	{"%v", &renamedStringVal},
   727  	{"%v", &renamedBytesVal},
   728  	{"%v", &renamedIntVal},
   729  	{"%v", &renamedUintVal},
   730  	{"%v", &renamedBoolVal},
   731  	{"%v", &renamedFloat32Val},
   732  	{"%v", &renamedComplex64Val},
   733  }
   734  
   735  func TestEOFAllTypes(t *testing.T) {
   736  	for i, test := range eofTests {
   737  		if _, err := Sscanf("", test.format, test.v); err != io.EOF {
   738  			t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err)
   739  		}
   740  		if _, err := Sscanf("   ", test.format, test.v); err != io.EOF {
   741  			t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err)
   742  		}
   743  	}
   744  }
   745  
   746  // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
   747  // calls to Fscan do not lose runes.
   748  func TestUnreadRuneWithBufio(t *testing.T) {
   749  	r := bufio.NewReader(strings.NewReader("123αb"))
   750  	var i int
   751  	var a string
   752  	n, err := Fscanf(r, "%d", &i)
   753  	if n != 1 || err != nil {
   754  		t.Errorf("reading int expected one item, no errors; got %d %q", n, err)
   755  	}
   756  	if i != 123 {
   757  		t.Errorf("expected 123; got %d", i)
   758  	}
   759  	n, err = Fscanf(r, "%s", &a)
   760  	if n != 1 || err != nil {
   761  		t.Errorf("reading string expected one item, no errors; got %d %q", n, err)
   762  	}
   763  	if a != "αb" {
   764  		t.Errorf("expected αb; got %q", a)
   765  	}
   766  }
   767  
   768  type TwoLines string
   769  
   770  // Scan attempts to read two lines into the object.  Scanln should prevent this
   771  // because it stops at newline; Scan and Scanf should be fine.
   772  func (t *TwoLines) Scan(state ScanState, verb rune) error {
   773  	chars := make([]rune, 0, 100)
   774  	for nlCount := 0; nlCount < 2; {
   775  		c, _, err := state.ReadRune()
   776  		if err != nil {
   777  			return err
   778  		}
   779  		chars = append(chars, c)
   780  		if c == '\n' {
   781  			nlCount++
   782  		}
   783  	}
   784  	*t = TwoLines(string(chars))
   785  	return nil
   786  }
   787  
   788  func TestMultiLine(t *testing.T) {
   789  	input := "abc\ndef\n"
   790  	// Sscan should work
   791  	var tscan TwoLines
   792  	n, err := Sscan(input, &tscan)
   793  	if n != 1 {
   794  		t.Errorf("Sscan: expected 1 item; got %d", n)
   795  	}
   796  	if err != nil {
   797  		t.Errorf("Sscan: expected no error; got %s", err)
   798  	}
   799  	if string(tscan) != input {
   800  		t.Errorf("Sscan: expected %q; got %q", input, tscan)
   801  	}
   802  	// Sscanf should work
   803  	var tscanf TwoLines
   804  	n, err = Sscanf(input, "%s", &tscanf)
   805  	if n != 1 {
   806  		t.Errorf("Sscanf: expected 1 item; got %d", n)
   807  	}
   808  	if err != nil {
   809  		t.Errorf("Sscanf: expected no error; got %s", err)
   810  	}
   811  	if string(tscanf) != input {
   812  		t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
   813  	}
   814  	// Sscanln should not work
   815  	var tscanln TwoLines
   816  	n, err = Sscanln(input, &tscanln)
   817  	if n != 0 {
   818  		t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
   819  	}
   820  	if err == nil {
   821  		t.Error("Sscanln: expected error; got none")
   822  	} else if err != io.ErrUnexpectedEOF {
   823  		t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err)
   824  	}
   825  }
   826  
   827  // simpleReader is a strings.Reader that implements only Read, not ReadRune.
   828  // Good for testing readahead.
   829  type simpleReader struct {
   830  	sr *strings.Reader
   831  }
   832  
   833  func (s *simpleReader) Read(b []byte) (n int, err error) {
   834  	return s.sr.Read(b)
   835  }
   836  
   837  // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
   838  // 3481.
   839  func TestLineByLineFscanf(t *testing.T) {
   840  	r := &simpleReader{strings.NewReader("1\n2\n")}
   841  	var i, j int
   842  	n, err := Fscanf(r, "%v\n", &i)
   843  	if n != 1 || err != nil {
   844  		t.Fatalf("first read: %d %q", n, err)
   845  	}
   846  	n, err = Fscanf(r, "%v\n", &j)
   847  	if n != 1 || err != nil {
   848  		t.Fatalf("second read: %d %q", n, err)
   849  	}
   850  	if i != 1 || j != 2 {
   851  		t.Errorf("wrong values; wanted 1 2 got %d %d", i, j)
   852  	}
   853  }
   854  
   855  // TestScanStateCount verifies the correct byte count is returned. Issue 8512.
   856  
   857  // runeScanner implements the Scanner interface for TestScanStateCount.
   858  type runeScanner struct {
   859  	rune rune
   860  	size int
   861  }
   862  
   863  func (rs *runeScanner) Scan(state ScanState, verb rune) error {
   864  	r, size, err := state.ReadRune()
   865  	rs.rune = r
   866  	rs.size = size
   867  	return err
   868  }
   869  
   870  func TestScanStateCount(t *testing.T) {
   871  	var a, b, c runeScanner
   872  	n, err := Sscanf("12➂", "%c%c%c", &a, &b, &c)
   873  	if err != nil {
   874  		t.Fatal(err)
   875  	}
   876  	if n != 3 {
   877  		t.Fatalf("expected 3 items consumed, got %d", n)
   878  	}
   879  	if a.rune != '1' || b.rune != '2' || c.rune != '➂' {
   880  		t.Errorf("bad scan rune: %q %q %q should be '1' '2' '➂'", a.rune, b.rune, c.rune)
   881  	}
   882  	if a.size != 1 || b.size != 1 || c.size != 3 {
   883  		t.Errorf("bad scan size: %q %q %q should be 1 1 3", a.size, b.size, c.size)
   884  	}
   885  }
   886  
   887  // RecursiveInt accepts a string matching %d.%d.%d....
   888  // and parses it into a linked list.
   889  // It allows us to benchmark recursive descent style scanners.
   890  type RecursiveInt struct {
   891  	i    int
   892  	next *RecursiveInt
   893  }
   894  
   895  func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
   896  	_, err = Fscan(state, &r.i)
   897  	if err != nil {
   898  		return
   899  	}
   900  	next := new(RecursiveInt)
   901  	_, err = Fscanf(state, ".%v", next)
   902  	if err != nil {
   903  		if err == io.ErrUnexpectedEOF {
   904  			err = nil
   905  		}
   906  		return
   907  	}
   908  	r.next = next
   909  	return
   910  }
   911  
   912  // scanInts performs the same scanning task as RecursiveInt.Scan
   913  // but without recurring through scanner, so we can compare
   914  // performance more directly.
   915  func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) {
   916  	r.next = nil
   917  	_, err = Fscan(b, &r.i)
   918  	if err != nil {
   919  		return
   920  	}
   921  	c, _, err := b.ReadRune()
   922  	if err != nil {
   923  		if err == io.EOF {
   924  			err = nil
   925  		}
   926  		return
   927  	}
   928  	if c != '.' {
   929  		return
   930  	}
   931  	next := new(RecursiveInt)
   932  	err = scanInts(next, b)
   933  	if err == nil {
   934  		r.next = next
   935  	}
   936  	return
   937  }
   938  
   939  func makeInts(n int) []byte {
   940  	var buf bytes.Buffer
   941  	Fprintf(&buf, "1")
   942  	for i := 1; i < n; i++ {
   943  		Fprintf(&buf, ".%d", i+1)
   944  	}
   945  	return buf.Bytes()
   946  }
   947  
   948  func TestScanInts(t *testing.T) {
   949  	testScanInts(t, scanInts)
   950  	testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
   951  		_, err = Fscan(b, r)
   952  		return
   953  	})
   954  }
   955  
   956  // 800 is small enough to not overflow the stack when using gccgo on a
   957  // platform that does not support split stack.
   958  const intCount = 800
   959  
   960  func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) {
   961  	r := new(RecursiveInt)
   962  	ints := makeInts(intCount)
   963  	buf := bytes.NewBuffer(ints)
   964  	err := scan(r, buf)
   965  	if err != nil {
   966  		t.Error("unexpected error", err)
   967  	}
   968  	i := 1
   969  	for ; r != nil; r = r.next {
   970  		if r.i != i {
   971  			t.Fatalf("bad scan: expected %d got %d", i, r.i)
   972  		}
   973  		i++
   974  	}
   975  	if i-1 != intCount {
   976  		t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
   977  	}
   978  }
   979  
   980  func BenchmarkScanInts(b *testing.B) {
   981  	b.ResetTimer()
   982  	ints := makeInts(intCount)
   983  	var r RecursiveInt
   984  	for i := b.N - 1; i >= 0; i-- {
   985  		buf := bytes.NewBuffer(ints)
   986  		b.StartTimer()
   987  		scanInts(&r, buf)
   988  		b.StopTimer()
   989  	}
   990  }
   991  
   992  func BenchmarkScanRecursiveInt(b *testing.B) {
   993  	b.ResetTimer()
   994  	ints := makeInts(intCount)
   995  	var r RecursiveInt
   996  	for i := b.N - 1; i >= 0; i-- {
   997  		buf := bytes.NewBuffer(ints)
   998  		b.StartTimer()
   999  		Fscan(buf, &r)
  1000  		b.StopTimer()
  1001  	}
  1002  }
  1003  
  1004  // Issue 9124.
  1005  // %x on bytes couldn't handle non-space bytes terminating the scan.
  1006  func TestHexBytes(t *testing.T) {
  1007  	var a, b []byte
  1008  	n, err := Sscanf("00010203", "%x", &a)
  1009  	if n != 1 || err != nil {
  1010  		t.Errorf("simple: got count, err = %d, %v; expected 1, nil", n, err)
  1011  	}
  1012  	check := func(msg string, x []byte) {
  1013  		if len(x) != 4 {
  1014  			t.Errorf("%s: bad length %d", msg, len(x))
  1015  		}
  1016  		for i, b := range x {
  1017  			if int(b) != i {
  1018  				t.Errorf("%s: bad x[%d] = %x", msg, i, x[i])
  1019  			}
  1020  		}
  1021  	}
  1022  	check("simple", a)
  1023  	a = nil
  1024  
  1025  	n, err = Sscanf("00010203 00010203", "%x %x", &a, &b)
  1026  	if n != 2 || err != nil {
  1027  		t.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n, err)
  1028  	}
  1029  	check("simple pair a", a)
  1030  	check("simple pair b", b)
  1031  	a = nil
  1032  	b = nil
  1033  
  1034  	n, err = Sscanf("00010203:", "%x", &a)
  1035  	if n != 1 || err != nil {
  1036  		t.Errorf("colon: got count, err = %d, %v; expected 1, nil", n, err)
  1037  	}
  1038  	check("colon", a)
  1039  	a = nil
  1040  
  1041  	n, err = Sscanf("00010203:00010203", "%x:%x", &a, &b)
  1042  	if n != 2 || err != nil {
  1043  		t.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n, err)
  1044  	}
  1045  	check("colon pair a", a)
  1046  	check("colon pair b", b)
  1047  	a = nil
  1048  	b = nil
  1049  
  1050  	// This one fails because there is a hex byte after the data,
  1051  	// that is, an odd number of hex input bytes.
  1052  	n, err = Sscanf("000102034:", "%x", &a)
  1053  	if n != 0 || err == nil {
  1054  		t.Errorf("odd count: got count, err = %d, %v; expected 0, error", n, err)
  1055  	}
  1056  }
  1057  
  1058  func TestScanNewlinesAreSpaces(t *testing.T) {
  1059  	var a, b int
  1060  	var tests = []struct {
  1061  		name  string
  1062  		text  string
  1063  		count int
  1064  	}{
  1065  		{"newlines", "1\n2\n", 2},
  1066  		{"no final newline", "1\n2", 2},
  1067  		{"newlines with spaces ", "1  \n  2  \n", 2},
  1068  		{"no final newline with spaces", "1  \n  2", 2},
  1069  	}
  1070  	for _, test := range tests {
  1071  		n, err := Sscan(test.text, &a, &b)
  1072  		if n != test.count {
  1073  			t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
  1074  		}
  1075  		if err != nil {
  1076  			t.Errorf("%s: unexpected error: %s", test.name, err)
  1077  		}
  1078  	}
  1079  }
  1080  
  1081  func TestScanlnNewlinesTerminate(t *testing.T) {
  1082  	var a, b int
  1083  	var tests = []struct {
  1084  		name  string
  1085  		text  string
  1086  		count int
  1087  		ok    bool
  1088  	}{
  1089  		{"one line one item", "1\n", 1, false},
  1090  		{"one line two items with spaces ", "   1 2    \n", 2, true},
  1091  		{"one line two items no newline", "   1 2", 2, true},
  1092  		{"two lines two items", "1\n2\n", 1, false},
  1093  	}
  1094  	for _, test := range tests {
  1095  		n, err := Sscanln(test.text, &a, &b)
  1096  		if n != test.count {
  1097  			t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
  1098  		}
  1099  		if test.ok && err != nil {
  1100  			t.Errorf("%s: unexpected error: %s", test.name, err)
  1101  		}
  1102  		if !test.ok && err == nil {
  1103  			t.Errorf("%s: expected error; got none", test.name)
  1104  		}
  1105  	}
  1106  }
  1107  
  1108  func TestScanfNewlineMatchFormat(t *testing.T) {
  1109  	var a, b int
  1110  	var tests = []struct {
  1111  		name   string
  1112  		text   string
  1113  		format string
  1114  		count  int
  1115  		ok     bool
  1116  	}{
  1117  		{"newline in both", "1\n2", "%d\n%d", 2, true},
  1118  		{"newline in input", "1\n2", "%d %d", 1, false},
  1119  		{"extra newline in format", "1\n2", "%d\n%d\n", 2, false},
  1120  		{"newline-newline in both", "1\n\n2", "%d\n\n%d", 2, true},
  1121  		{"newline-newline in format", "1\n2", "%d\n\n%d", 1, false},
  1122  		{"newline-newline in input", "1\n\n2", "%d\n%d", 1, false},
  1123  		{"space-newline in input", "1 \n2", "%d %d", 1, false},
  1124  		{"newline in format", "1 2", "%d\n%d", 1, false},
  1125  		{"space-newline in format", "1 2", "%d \n%d", 1, false},
  1126  		{"space-newline in both", "1 \n2", "%d \n%d", 2, true},
  1127  		{"extra space in format", "1\n2", "%d\n %d", 2, true},
  1128  		{"two extra spaces in format", "1\n2", "%d \n %d", 2, true},
  1129  		{"newline start in both", "\n1 2", "\n%d %d", 2, true},
  1130  		{"newline start in format", "1 2", "\n%d %d", 0, false},
  1131  		{"newline start in input", "\n1 2", "%d %d", 0, false},
  1132  		{"space-newline start in input", " \n1 2", "\n%d %d", 2, true},
  1133  	}
  1134  	for _, test := range tests {
  1135  		n, err := Sscanf(test.text, test.format, &a, &b)
  1136  		if n != test.count {
  1137  			t.Errorf("%s: expected to scan %d item(s), scanned %d", test.name, test.count, n)
  1138  		}
  1139  		if test.ok && err != nil {
  1140  			t.Errorf("%s: unexpected error: %s", test.name, err)
  1141  		}
  1142  		if !test.ok && err == nil {
  1143  			t.Errorf("%s: expected error; got none", test.name)
  1144  		}
  1145  	}
  1146  }
  1147  
  1148  // Test for issue 12090: Was unreading at EOF, double-scanning a byte.
  1149  
  1150  type hexBytes [2]byte
  1151  
  1152  func (h *hexBytes) Scan(ss ScanState, verb rune) error {
  1153  	var b []byte
  1154  	_, err := Fscanf(ss, "%4x", &b)
  1155  	if err != nil {
  1156  		panic(err) // Really shouldn't happen.
  1157  	}
  1158  	copy((*h)[:], b)
  1159  	return err
  1160  }
  1161  
  1162  func TestHexByte(t *testing.T) {
  1163  	var h hexBytes
  1164  	n, err := Sscanln("0123\n", &h)
  1165  	if err != nil {
  1166  		t.Fatal(err)
  1167  	}
  1168  	if n != 1 {
  1169  		t.Fatalf("expected 1 item; scanned %d", n)
  1170  	}
  1171  	if h[0] != 0x01 || h[1] != 0x23 {
  1172  		t.Fatalf("expected 0123 got %x", h)
  1173  	}
  1174  }