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.
22 type ScanTest
struct {
28 type ScanfTest
struct {
35 type ScanfMultiTest
struct {
60 complex64Val complex64
61 complex128Val complex128
62 renamedBoolVal renamedBool
63 renamedIntVal renamedInt
64 renamedInt8Val renamedInt8
65 renamedInt16Val renamedInt16
66 renamedInt32Val renamedInt32
67 renamedInt64Val renamedInt64
68 renamedUintVal renamedUint
69 renamedUint8Val renamedUint8
70 renamedUint16Val renamedUint16
71 renamedUint32Val renamedUint32
72 renamedUint64Val renamedUint64
73 renamedUintptrVal renamedUintptr
74 renamedStringVal renamedString
75 renamedBytesVal renamedBytes
76 renamedFloat32Val renamedFloat32
77 renamedFloat64Val renamedFloat64
78 renamedComplex64Val renamedComplex64
79 renamedComplex128Val renamedComplex128
82 // Xs accepts any non-empty run of the verb character
85 func (x
*Xs
) Scan(state ScanState
, verb rune
) error
{
86 tok
, err
:= state
.Token(true, func(r rune
) bool { return r
== verb
})
91 if !regexp
.MustCompile("^" + string(verb
) + "+$").MatchString(s
) {
92 return errors
.New("syntax error for xs")
100 // IntString accepts an integer followed immediately by a string.
101 // It tests the embedding of a scan within a scan.
102 type IntString
struct {
107 func (s
*IntString
) Scan(state ScanState
, verb rune
) error
{
108 if _
, err
:= Fscan(state
, &s
.i
); err
!= nil {
112 tok
, err
:= state
.Token(true, nil)
120 var intStringVal IntString
122 var scanTests
= []ScanTest
{
124 {"T\n", &boolVal
, true}, // boolean test vals toggle to be sure they are written
125 {"F\n", &boolVal
, false}, // restored to zero value
126 {"21\n", &intVal
, 21},
128 {"000\n", &intVal
, 0},
129 {"0x10\n", &intVal
, 0x10},
130 {"-0x10\n", &intVal
, -0x10},
131 {"0377\n", &intVal
, 0377},
132 {"-0377\n", &intVal
, -0377},
133 {"0\n", &uintVal
, uint(0)},
134 {"000\n", &uintVal
, uint(0)},
135 {"0x10\n", &uintVal
, uint(0x10)},
136 {"0377\n", &uintVal
, uint(0377)},
137 {"22\n", &int8Val
, int8(22)},
138 {"23\n", &int16Val
, int16(23)},
139 {"24\n", &int32Val
, int32(24)},
140 {"25\n", &int64Val
, int64(25)},
141 {"127\n", &int8Val
, int8(127)},
142 {"-21\n", &intVal
, -21},
143 {"-22\n", &int8Val
, int8(-22)},
144 {"-23\n", &int16Val
, int16(-23)},
145 {"-24\n", &int32Val
, int32(-24)},
146 {"-25\n", &int64Val
, int64(-25)},
147 {"-128\n", &int8Val
, int8(-128)},
148 {"+21\n", &intVal
, +21},
149 {"+22\n", &int8Val
, int8(+22)},
150 {"+23\n", &int16Val
, int16(+23)},
151 {"+24\n", &int32Val
, int32(+24)},
152 {"+25\n", &int64Val
, int64(+25)},
153 {"+127\n", &int8Val
, int8(+127)},
154 {"26\n", &uintVal
, uint(26)},
155 {"27\n", &uint8Val
, uint8(27)},
156 {"28\n", &uint16Val
, uint16(28)},
157 {"29\n", &uint32Val
, uint32(29)},
158 {"30\n", &uint64Val
, uint64(30)},
159 {"255\n", &uint8Val
, uint8(255)},
160 {"32767\n", &int16Val
, int16(32767)},
161 {"2.3\n", &float64Val
, 2.3},
162 {"2.3e1\n", &float32Val
, float32(2.3e1
)},
163 {"2.3e2\n", &float64Val
, 2.3e2
},
164 {"2.3p2\n", &float64Val
, 2.3 * 4},
165 {"2.3p+2\n", &float64Val
, 2.3 * 4},
166 {"2.3p+66\n", &float64Val
, 2.3 * (1 << 32) * (1 << 32) * 4},
167 {"2.3p-66\n", &float64Val
, 2.3 / ((1 << 32) * (1 << 32) * 4)},
168 {"2.35\n", &stringVal
, "2.35"},
169 {"2345678\n", &bytesVal
, []byte("2345678")},
170 {"(3.4e1-2i)\n", &complex128Val
, 3.4e1
- 2i
},
171 {"-3.45e1-3i\n", &complex64Val
, complex64(-3.45e1
- 3i
)},
172 {"-.45e1-1e2i\n", &complex128Val
, complex128(-.45e1
- 100i
)},
173 {"hello\n", &stringVal
, "hello"},
175 // Carriage-return followed by newline. (We treat \r\n as \n always.)
176 {"hello\r\n", &stringVal
, "hello"},
177 {"27\r\n", &uint8Val
, uint8(27)},
180 {"true\n", &renamedBoolVal
, renamedBool(true)},
181 {"F\n", &renamedBoolVal
, renamedBool(false)},
182 {"101\n", &renamedIntVal
, renamedInt(101)},
183 {"102\n", &renamedIntVal
, renamedInt(102)},
184 {"103\n", &renamedUintVal
, renamedUint(103)},
185 {"104\n", &renamedUintVal
, renamedUint(104)},
186 {"105\n", &renamedInt8Val
, renamedInt8(105)},
187 {"106\n", &renamedInt16Val
, renamedInt16(106)},
188 {"107\n", &renamedInt32Val
, renamedInt32(107)},
189 {"108\n", &renamedInt64Val
, renamedInt64(108)},
190 {"109\n", &renamedUint8Val
, renamedUint8(109)},
191 {"110\n", &renamedUint16Val
, renamedUint16(110)},
192 {"111\n", &renamedUint32Val
, renamedUint32(111)},
193 {"112\n", &renamedUint64Val
, renamedUint64(112)},
194 {"113\n", &renamedUintptrVal
, renamedUintptr(113)},
195 {"114\n", &renamedStringVal
, renamedString("114")},
196 {"115\n", &renamedBytesVal
, renamedBytes([]byte("115"))},
199 {" vvv ", &xVal
, Xs("vvv")},
200 {" 1234hello", &intStringVal
, IntString
{1234, "hello"}},
203 {"2147483648\n", &int64Val
, int64(2147483648)}, // was: integer overflow
206 var scanfTests
= []ScanfTest
{
207 {"%v", "TRUE\n", &boolVal
, true},
208 {"%t", "false\n", &boolVal
, false},
209 {"%v", "-71\n", &intVal
, -71},
210 {"%v", "0377\n", &intVal
, 0377},
211 {"%v", "0x44\n", &intVal
, 0x44},
212 {"%d", "72\n", &intVal
, 72},
213 {"%c", "a\n", &runeVal
, 'a'},
214 {"%c", "\u5072\n", &runeVal
, '\u5072'},
215 {"%c", "\u1234\n", &runeVal
, '\u1234'},
216 {"%d", "73\n", &int8Val
, int8(73)},
217 {"%d", "+74\n", &int16Val
, int16(74)},
218 {"%d", "75\n", &int32Val
, int32(75)},
219 {"%d", "76\n", &int64Val
, int64(76)},
220 {"%b", "1001001\n", &intVal
, 73},
221 {"%o", "075\n", &intVal
, 075},
222 {"%x", "a75\n", &intVal
, 0xa75},
223 {"%v", "71\n", &uintVal
, uint(71)},
224 {"%d", "72\n", &uintVal
, uint(72)},
225 {"%d", "73\n", &uint8Val
, uint8(73)},
226 {"%d", "74\n", &uint16Val
, uint16(74)},
227 {"%d", "75\n", &uint32Val
, uint32(75)},
228 {"%d", "76\n", &uint64Val
, uint64(76)},
229 {"%b", "1001001\n", &uintVal
, uint(73)},
230 {"%o", "075\n", &uintVal
, uint(075)},
231 {"%x", "a75\n", &uintVal
, uint(0xa75)},
232 {"%x", "A75\n", &uintVal
, uint(0xa75)},
233 {"%U", "U+1234\n", &intVal
, int(0x1234)},
234 {"%U", "U+4567\n", &uintVal
, uint(0x4567)},
237 {"%s", "using-%s\n", &stringVal
, "using-%s"},
238 {"%x", "7573696e672d2578\n", &stringVal
, "using-%x"},
239 {"%X", "7573696E672D2558\n", &stringVal
, "using-%X"},
240 {"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal
, "quoted\twith\\doubles"},
241 {"%q", "`quoted with backs`\n", &stringVal
, "quoted with backs"},
244 {"%s", "bytes-%s\n", &bytesVal
, []byte("bytes-%s")},
245 {"%x", "62797465732d2578\n", &bytesVal
, []byte("bytes-%x")},
246 {"%X", "62797465732D2558\n", &bytesVal
, []byte("bytes-%X")},
247 {"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal
, []byte("bytes\rwith\vdoubles")},
248 {"%q", "`bytes with backs`\n", &bytesVal
, []byte("bytes with backs")},
251 {"%v\n", "true\n", &renamedBoolVal
, renamedBool(true)},
252 {"%t\n", "F\n", &renamedBoolVal
, renamedBool(false)},
253 {"%v", "101\n", &renamedIntVal
, renamedInt(101)},
254 {"%c", "\u0101\n", &renamedIntVal
, renamedInt('\u0101')},
255 {"%o", "0146\n", &renamedIntVal
, renamedInt(102)},
256 {"%v", "103\n", &renamedUintVal
, renamedUint(103)},
257 {"%d", "104\n", &renamedUintVal
, renamedUint(104)},
258 {"%d", "105\n", &renamedInt8Val
, renamedInt8(105)},
259 {"%d", "106\n", &renamedInt16Val
, renamedInt16(106)},
260 {"%d", "107\n", &renamedInt32Val
, renamedInt32(107)},
261 {"%d", "108\n", &renamedInt64Val
, renamedInt64(108)},
262 {"%x", "6D\n", &renamedUint8Val
, renamedUint8(109)},
263 {"%o", "0156\n", &renamedUint16Val
, renamedUint16(110)},
264 {"%d", "111\n", &renamedUint32Val
, renamedUint32(111)},
265 {"%d", "112\n", &renamedUint64Val
, renamedUint64(112)},
266 {"%d", "113\n", &renamedUintptrVal
, renamedUintptr(113)},
267 {"%s", "114\n", &renamedStringVal
, renamedString("114")},
268 {"%q", "\"1155\"\n", &renamedBytesVal
, renamedBytes([]byte("1155"))},
269 {"%g", "116e1\n", &renamedFloat32Val
, renamedFloat32(116e1
)},
270 {"%g", "-11.7e+1", &renamedFloat64Val
, renamedFloat64(-11.7e+1)},
271 {"%g", "11+6e1i\n", &renamedComplex64Val
, renamedComplex64(11 + 6e1i
)},
272 {"%g", "-11.+7e+1i", &renamedComplex128Val
, renamedComplex128(-11. + 7e+1i
)},
274 // Interesting formats
275 {"here is\tthe value:%d", "here is the\tvalue:118\n", &intVal
, 118},
276 {"%% %%:%d", "% %:119\n", &intVal
, 119},
277 {"%d%%", "42%", &intVal
, 42}, // %% at end of string.
280 {"%x", "FFFFFFFF\n", &uint32Val
, uint32(0xFFFFFFFF)},
283 {"%s", " sss ", &xVal
, Xs("sss")},
284 {"%2s", "sssss", &xVal
, Xs("ss")},
287 {"%d\n", "27\n", &intVal
, 27}, // ok
288 {"%d\n", "28 \n", &intVal
, 28}, // was: "unexpected newline"
289 {"%v", "0", &intVal
, 0}, // was: "EOF"; 0 was taken as base prefix and not counted.
290 {"%v", "0", &uintVal
, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
291 {"%c", " ", &uintVal
, uint(' ')}, // %c must accept a blank.
292 {"%c", "\t", &uintVal
, uint('\t')}, // %c must accept any space.
293 {"%c", "\n", &uintVal
, uint('\n')}, // %c must accept any space.
296 var overflowTests
= []ScanTest
{
297 {"128", &int8Val
, 0},
298 {"32768", &int16Val
, 0},
299 {"-129", &int8Val
, 0},
300 {"-32769", &int16Val
, 0},
301 {"256", &uint8Val
, 0},
302 {"65536", &uint16Val
, 0},
303 {"1e100", &float32Val
, 0},
304 {"1e500", &float64Val
, 0},
305 {"(1e100+0i)", &complex64Val
, 0},
306 {"(1+1e100i)", &complex64Val
, 0},
307 {"(1-1e500i)", &complex128Val
, 0},
319 var multiTests
= []ScanfMultiTest
{
320 {"", "", []interface{}{}, []interface{}{}, ""},
321 {"%d", "23", args(&i
), args(23), ""},
322 {"%2s%3s", "22333", args(&s
, &t
), args("22", "333"), ""},
323 {"%2d%3d", "44555", args(&i
, &j
), args(44, 555), ""},
324 {"%2d.%3d", "66.777", args(&i
, &j
), args(66, 777), ""},
325 {"%d, %d", "23, 18", args(&i
, &j
), args(23, 18), ""},
326 {"%3d22%3d", "33322333", args(&i
, &j
), args(333, 333), ""},
327 {"%6vX=%3fY", "3+2iX=2.5Y", args(&c
, &f
), args((3 + 2i
), 2.5), ""},
328 {"%d%s", "123abc", args(&i
, &s
), args(123, "abc"), ""},
329 {"%c%c%c", "2\u50c2X", args(&r1
, &r2
, &r3
), args('2', '\u50c2', 'X'), ""},
330 {"%5s%d", " 1234567 ", args(&s
, &i
), args("12345", 67), ""},
331 {"%5s%d", " 12 34 567 ", args(&s
, &i
), args("12", 34), ""},
334 {"%e%f", "eefffff", args(&x
, &y
), args(Xs("ee"), Xs("fffff")), ""},
335 {"%4v%s", "12abcd", args(&z
, &s
), args(IntString
{12, "ab"}, "cd"), ""},
338 {"%t", "23 18", args(&i
), nil, "bad verb"},
339 {"%d %d %d", "23 18", args(&i
, &j
), args(23, 18), "too few operands"},
340 {"%d %d", "23 18 27", args(&i
, &j
, &k
), args(23, 18), "too many operands"},
341 {"%c", "\u0100", args(&int8Val
), nil, "overflow"},
342 {"X%d", "10X", args(&intVal
), nil, "input does not match format"},
343 {"%d%", "42%", args(&intVal
), args(42), "missing verb: % at end of format string"},
344 {"%d% ", "42%", args(&intVal
), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct.
346 // Bad UTF-8: should see every byte.
347 {"%c%c%c", "\xc2X\xc2", args(&r1
, &r2
, &r3
), args(utf8
.RuneError
, 'X', utf8
.RuneError
), ""},
350 {"%v%v", "FALSE23", args(&truth
, &i
), args(false, 23), ""},
353 var readers
= []struct {
355 f
func(string) io
.Reader
357 {"StringReader", func(s
string) io
.Reader
{
358 return strings
.NewReader(s
)
360 {"ReaderOnly", func(s
string) io
.Reader
{
361 return struct{ io
.Reader
}{strings
.NewReader(s
)}
363 {"OneByteReader", func(s
string) io
.Reader
{
364 return iotest
.OneByteReader(strings
.NewReader(s
))
366 {"DataErrReader", func(s
string) io
.Reader
{
367 return iotest
.DataErrReader(strings
.NewReader(s
))
371 func testScan(t
*testing
.T
, f
func(string) io
.Reader
, scan
func(r io
.Reader
, a
...interface{}) (int, error
)) {
372 for _
, test
:= range scanTests
{
374 n
, err
:= scan(r
, test
.in
)
378 m
= Sprintf(" (%d fields ok)", n
)
380 t
.Errorf("got error scanning %q: %s%s", test
.text
, err
, m
)
384 t
.Errorf("count error on entry %q: got %d", test
.text
, n
)
387 // The incoming value may be a pointer
388 v
:= reflect
.ValueOf(test
.in
)
389 if p
:= v
; p
.Kind() == reflect
.Ptr
{
393 if !reflect
.DeepEqual(val
, test
.out
) {
394 t
.Errorf("scanning %q: expected %#v got %#v, type %T", test
.text
, test
.out
, val
, val
)
399 func TestScan(t
*testing
.T
) {
400 for _
, r
:= range readers
{
401 t
.Run(r
.name
, func(t
*testing
.T
) {
402 testScan(t
, r
.f
, Fscan
)
407 func TestScanln(t
*testing
.T
) {
408 for _
, r
:= range readers
{
409 t
.Run(r
.name
, func(t
*testing
.T
) {
410 testScan(t
, r
.f
, Fscanln
)
415 func TestScanf(t
*testing
.T
) {
416 for _
, test
:= range scanfTests
{
417 n
, err
:= Sscanf(test
.text
, test
.format
, test
.in
)
419 t
.Errorf("got error scanning (%q, %q): %s", test
.format
, test
.text
, err
)
423 t
.Errorf("count error on entry (%q, %q): got %d", test
.format
, test
.text
, n
)
426 // The incoming value may be a pointer
427 v
:= reflect
.ValueOf(test
.in
)
428 if p
:= v
; p
.Kind() == reflect
.Ptr
{
432 if !reflect
.DeepEqual(val
, test
.out
) {
433 t
.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test
.format
, test
.text
, test
.out
, val
, val
)
438 func TestScanOverflow(t
*testing
.T
) {
439 // different machines and different types report errors with different strings.
440 re
:= regexp
.MustCompile("overflow|too large|out of range|not representable")
441 for _
, test
:= range overflowTests
{
442 _
, err
:= Sscan(test
.text
, test
.in
)
444 t
.Errorf("expected overflow scanning %q", test
.text
)
447 if !re
.MatchString(err
.Error()) {
448 t
.Errorf("expected overflow error scanning %q: %s", test
.text
, err
)
453 func verifyNaN(str
string, t
*testing
.T
) {
457 text
:= str
+ " " + str
+ " " + str
458 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
460 t
.Errorf("got error scanning %q: %s", text
, err
)
463 t
.Errorf("count error scanning %q: got %d", text
, n
)
465 if !math
.IsNaN(float64(f
)) ||
!math
.IsNaN(float64(f32
)) ||
!math
.IsNaN(f64
) {
466 t
.Errorf("didn't get NaNs scanning %q: got %g %g %g", text
, f
, f32
, f64
)
470 func TestNaN(t
*testing
.T
) {
471 for _
, s
:= range []string{"nan", "NAN", "NaN"} {
476 func verifyInf(str
string, t
*testing
.T
) {
480 text
:= str
+ " " + str
+ " " + str
481 n
, err
:= Fscan(strings
.NewReader(text
), &f
, &f32
, &f64
)
483 t
.Errorf("got error scanning %q: %s", text
, err
)
486 t
.Errorf("count error scanning %q: got %d", text
, n
)
492 if !math
.IsInf(float64(f
), sign
) ||
!math
.IsInf(float64(f32
), sign
) ||
!math
.IsInf(f64
, sign
) {
493 t
.Errorf("didn't get right Infs scanning %q: got %g %g %g", text
, f
, f32
, f64
)
497 func TestInf(t
*testing
.T
) {
498 for _
, s
:= range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
503 func testScanfMulti(t
*testing
.T
, f
func(string) io
.Reader
) {
504 sliceType
:= reflect
.TypeOf(make([]interface{}, 1))
505 for _
, test
:= range multiTests
{
507 n
, err
:= Fscanf(r
, test
.format
, test
.in
...)
510 t
.Errorf("got error scanning (%q, %q): %q", test
.format
, test
.text
, err
)
511 } else if !strings
.Contains(err
.Error(), test
.err
) {
512 t
.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test
.format
, test
.text
, err
, test
.err
)
517 t
.Errorf("expected error %q error scanning (%q, %q)", test
.err
, test
.format
, test
.text
)
519 if n
!= len(test
.out
) {
520 t
.Errorf("count error on entry (%q, %q): expected %d got %d", test
.format
, test
.text
, len(test
.out
), n
)
523 // Convert the slice of pointers into a slice of values
524 resultVal
:= reflect
.MakeSlice(sliceType
, n
, n
)
525 for i
:= 0; i
< n
; i
++ {
526 v
:= reflect
.ValueOf(test
.in
[i
]).Elem()
527 resultVal
.Index(i
).Set(v
)
529 result
:= resultVal
.Interface()
530 if !reflect
.DeepEqual(result
, test
.out
) {
531 t
.Errorf("scanning (%q, %q): expected %#v got %#v", test
.format
, test
.text
, test
.out
, result
)
536 func TestScanfMulti(t
*testing
.T
) {
537 for _
, r
:= range readers
{
538 t
.Run(r
.name
, func(t
*testing
.T
) {
539 testScanfMulti(t
, r
.f
)
544 func TestScanMultiple(t
*testing
.T
) {
547 n
, err
:= Sscan("123abc", &a
, &s
)
549 t
.Errorf("Sscan count error: expected 2: got %d", n
)
552 t
.Errorf("Sscan expected no error; got %s", err
)
554 if a
!= 123 || s
!= "abc" {
555 t
.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a
, s
)
557 n
, err
= Sscan("asdf", &s
, &a
)
559 t
.Errorf("Sscan count error: expected 1: got %d", n
)
562 t
.Errorf("Sscan expected error; got none: %s", err
)
565 t
.Errorf("Sscan wrong values: got %q expected \"asdf\"", s
)
569 // Empty strings are not valid input when scanning a string.
570 func TestScanEmpty(t
*testing
.T
) {
572 n
, err
:= Sscan("abc", &s1
, &s2
)
574 t
.Errorf("Sscan count error: expected 1: got %d", n
)
577 t
.Error("Sscan <one item> expected error; got none")
580 t
.Errorf("Sscan wrong values: got %q expected \"abc\"", s1
)
582 n
, err
= Sscan("", &s1
, &s2
)
584 t
.Errorf("Sscan count error: expected 0: got %d", n
)
587 t
.Error("Sscan <empty> expected error; got none")
589 // Quoted empty string is OK.
590 n
, err
= Sscanf(`""`, "%q", &s1
)
592 t
.Errorf("Sscanf count error: expected 1: got %d", n
)
595 t
.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err
)
599 func TestScanNotPointer(t
*testing
.T
) {
600 r
:= strings
.NewReader("1")
602 _
, err
:= Fscan(r
, a
)
604 t
.Error("expected error scanning non-pointer")
605 } else if !strings
.Contains(err
.Error(), "pointer") {
606 t
.Errorf("expected pointer error scanning non-pointer, got: %s", err
)
610 func TestScanlnNoNewline(t
*testing
.T
) {
612 _
, err
:= Sscanln("1 x\n", &a
)
614 t
.Error("expected error scanning string missing newline")
615 } else if !strings
.Contains(err
.Error(), "newline") {
616 t
.Errorf("expected newline error scanning string missing newline, got: %s", err
)
620 func TestScanlnWithMiddleNewline(t
*testing
.T
) {
621 r
:= strings
.NewReader("123\n456\n")
623 _
, err
:= Fscanln(r
, &a
, &b
)
625 t
.Error("expected error scanning string with extra newline")
626 } else if !strings
.Contains(err
.Error(), "newline") {
627 t
.Errorf("expected newline error scanning string with extra newline, got: %s", err
)
631 // eofCounter is a special Reader that counts reads at end of file.
632 type eofCounter
struct {
633 reader
*strings
.Reader
637 func (ec
*eofCounter
) Read(b
[]byte) (n
int, err error
) {
638 n
, err
= ec
.reader
.Read(b
)
645 // TestEOF verifies that when we scan, we see at most EOF once per call to a
646 // Scan function, and then only when it's really an EOF.
647 func TestEOF(t
*testing
.T
) {
648 ec
:= &eofCounter
{strings
.NewReader("123\n"), 0}
650 n
, err
:= Fscanln(ec
, &a
)
652 t
.Error("unexpected error", err
)
655 t
.Error("expected to scan one item, got", n
)
657 if ec
.eofCount
!= 0 {
658 t
.Error("expected zero EOFs", ec
.eofCount
)
659 ec
.eofCount
= 0 // reset for next test
661 n
, err
= Fscanln(ec
, &a
)
663 t
.Error("expected error scanning empty string")
666 t
.Error("expected to scan zero items, got", n
)
668 if ec
.eofCount
!= 1 {
669 t
.Error("expected one EOF, got", ec
.eofCount
)
673 // TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
674 // This was a buglet: we used to get "expected integer".
675 func TestEOFAtEndOfInput(t
*testing
.T
) {
677 n
, err
:= Sscanf("23", "%d %d", &i
, &j
)
678 if n
!= 1 || i
!= 23 {
679 t
.Errorf("Sscanf expected one value of 23; got %d %d", n
, i
)
682 t
.Errorf("Sscanf expected EOF; got %q", err
)
684 n
, err
= Sscan("234", &i
, &j
)
685 if n
!= 1 || i
!= 234 {
686 t
.Errorf("Sscan expected one value of 234; got %d %d", n
, i
)
689 t
.Errorf("Sscan expected EOF; got %q", err
)
691 // Trailing space is tougher.
692 n
, err
= Sscan("234 ", &i
, &j
)
693 if n
!= 1 || i
!= 234 {
694 t
.Errorf("Sscan expected one value of 234; got %d %d", n
, i
)
697 t
.Errorf("Sscan expected EOF; got %q", err
)
701 var eofTests
= []struct {
714 {"%v", &complex64Val
},
715 {"%v", &renamedStringVal
},
716 {"%v", &renamedBytesVal
},
717 {"%v", &renamedIntVal
},
718 {"%v", &renamedUintVal
},
719 {"%v", &renamedBoolVal
},
720 {"%v", &renamedFloat32Val
},
721 {"%v", &renamedComplex64Val
},
724 func TestEOFAllTypes(t
*testing
.T
) {
725 for i
, test
:= range eofTests
{
726 if _
, err
:= Sscanf("", test
.format
, test
.v
); err
!= io
.EOF
{
727 t
.Errorf("#%d: %s %T not eof on empty string: %s", i
, test
.format
, test
.v
, err
)
729 if _
, err
:= Sscanf(" ", test
.format
, test
.v
); err
!= io
.EOF
{
730 t
.Errorf("#%d: %s %T not eof on trailing blanks: %s", i
, test
.format
, test
.v
, err
)
735 // TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
736 // calls to Fscan do not lose runes.
737 func TestUnreadRuneWithBufio(t
*testing
.T
) {
738 r
:= bufio
.NewReader(strings
.NewReader("123αb"))
741 n
, err
:= Fscanf(r
, "%d", &i
)
742 if n
!= 1 || err
!= nil {
743 t
.Errorf("reading int expected one item, no errors; got %d %q", n
, err
)
746 t
.Errorf("expected 123; got %d", i
)
748 n
, err
= Fscanf(r
, "%s", &a
)
749 if n
!= 1 || err
!= nil {
750 t
.Errorf("reading string expected one item, no errors; got %d %q", n
, err
)
753 t
.Errorf("expected αb; got %q", a
)
759 // Scan attempts to read two lines into the object. Scanln should prevent this
760 // because it stops at newline; Scan and Scanf should be fine.
761 func (t
*TwoLines
) Scan(state ScanState
, verb rune
) error
{
762 chars
:= make([]rune
, 0, 100)
763 for nlCount
:= 0; nlCount
< 2; {
764 c
, _
, err
:= state
.ReadRune()
768 chars
= append(chars
, c
)
773 *t
= TwoLines(string(chars
))
777 func TestMultiLine(t
*testing
.T
) {
778 input
:= "abc\ndef\n"
781 n
, err
:= Sscan(input
, &tscan
)
783 t
.Errorf("Sscan: expected 1 item; got %d", n
)
786 t
.Errorf("Sscan: expected no error; got %s", err
)
788 if string(tscan
) != input
{
789 t
.Errorf("Sscan: expected %q; got %q", input
, tscan
)
791 // Sscanf should work
793 n
, err
= Sscanf(input
, "%s", &tscanf
)
795 t
.Errorf("Sscanf: expected 1 item; got %d", n
)
798 t
.Errorf("Sscanf: expected no error; got %s", err
)
800 if string(tscanf
) != input
{
801 t
.Errorf("Sscanf: expected %q; got %q", input
, tscanf
)
803 // Sscanln should not work
805 n
, err
= Sscanln(input
, &tscanln
)
807 t
.Errorf("Sscanln: expected 0 items; got %d: %q", n
, tscanln
)
810 t
.Error("Sscanln: expected error; got none")
811 } else if err
!= io
.ErrUnexpectedEOF
{
812 t
.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err
)
816 // TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
818 func TestLineByLineFscanf(t
*testing
.T
) {
819 r
:= struct{ io
.Reader
}{strings
.NewReader("1\n2\n")}
821 n
, err
:= Fscanf(r
, "%v\n", &i
)
822 if n
!= 1 || err
!= nil {
823 t
.Fatalf("first read: %d %q", n
, err
)
825 n
, err
= Fscanf(r
, "%v\n", &j
)
826 if n
!= 1 || err
!= nil {
827 t
.Fatalf("second read: %d %q", n
, err
)
829 if i
!= 1 || j
!= 2 {
830 t
.Errorf("wrong values; wanted 1 2 got %d %d", i
, j
)
834 // TestScanStateCount verifies the correct byte count is returned. Issue 8512.
836 // runeScanner implements the Scanner interface for TestScanStateCount.
837 type runeScanner
struct {
842 func (rs
*runeScanner
) Scan(state ScanState
, verb rune
) error
{
843 r
, size
, err
:= state
.ReadRune()
849 func TestScanStateCount(t
*testing
.T
) {
850 var a
, b
, c runeScanner
851 n
, err
:= Sscanf("12âž‚", "%c%c%c", &a
, &b
, &c
)
856 t
.Fatalf("expected 3 items consumed, got %d", n
)
858 if a
.rune
!= '1' || b
.rune
!= '2' || c
.rune
!= 'âž‚' {
859 t
.Errorf("bad scan rune: %q %q %q should be '1' '2' 'âž‚'", a
.rune
, b
.rune
, c
.rune
)
861 if a
.size
!= 1 || b
.size
!= 1 || c
.size
!= 3 {
862 t
.Errorf("bad scan size: %q %q %q should be 1 1 3", a
.size
, b
.size
, c
.size
)
866 // RecursiveInt accepts a string matching %d.%d.%d....
867 // and parses it into a linked list.
868 // It allows us to benchmark recursive descent style scanners.
869 type RecursiveInt
struct {
874 func (r
*RecursiveInt
) Scan(state ScanState
, verb rune
) (err error
) {
875 _
, err
= Fscan(state
, &r
.i
)
879 next
:= new(RecursiveInt
)
880 _
, err
= Fscanf(state
, ".%v", next
)
882 if err
== io
.ErrUnexpectedEOF
{
891 // scanInts performs the same scanning task as RecursiveInt.Scan
892 // but without recurring through scanner, so we can compare
893 // performance more directly.
894 func scanInts(r
*RecursiveInt
, b
*bytes
.Buffer
) (err error
) {
896 _
, err
= Fscan(b
, &r
.i
)
900 c
, _
, err
:= b
.ReadRune()
910 next
:= new(RecursiveInt
)
911 err
= scanInts(next
, b
)
918 func makeInts(n
int) []byte {
921 for i
:= 1; i
< n
; i
++ {
922 Fprintf(&buf
, ".%d", i
+1)
927 func TestScanInts(t
*testing
.T
) {
928 testScanInts(t
, scanInts
)
929 testScanInts(t
, func(r
*RecursiveInt
, b
*bytes
.Buffer
) (err error
) {
935 // 800 is small enough to not overflow the stack when using gccgo on a
936 // platform that does not support split stack.
939 func testScanInts(t
*testing
.T
, scan
func(*RecursiveInt
, *bytes
.Buffer
) error
) {
940 r
:= new(RecursiveInt
)
941 ints
:= makeInts(intCount
)
942 buf
:= bytes
.NewBuffer(ints
)
945 t
.Error("unexpected error", err
)
948 for ; r
!= nil; r
= r
.next
{
950 t
.Fatalf("bad scan: expected %d got %d", i
, r
.i
)
955 t
.Fatalf("bad scan count: expected %d got %d", intCount
, i
-1)
959 func BenchmarkScanInts(b
*testing
.B
) {
961 ints
:= makeInts(intCount
)
963 for i
:= b
.N
- 1; i
>= 0; i
-- {
964 buf
:= bytes
.NewBuffer(ints
)
971 func BenchmarkScanRecursiveInt(b
*testing
.B
) {
973 ints
:= makeInts(intCount
)
975 for i
:= b
.N
- 1; i
>= 0; i
-- {
976 buf
:= bytes
.NewBuffer(ints
)
983 func BenchmarkScanRecursiveIntReaderWrapper(b
*testing
.B
) {
985 ints
:= makeInts(intCount
)
987 for i
:= b
.N
- 1; i
>= 0; i
-- {
988 buf
:= struct{ io
.Reader
}{strings
.NewReader(string(ints
))}
996 // %x on bytes couldn't handle non-space bytes terminating the scan.
997 func TestHexBytes(t
*testing
.T
) {
999 n
, err
:= Sscanf("00010203", "%x", &a
)
1000 if n
!= 1 || err
!= nil {
1001 t
.Errorf("simple: got count, err = %d, %v; expected 1, nil", n
, err
)
1003 check
:= func(msg
string, x
[]byte) {
1005 t
.Errorf("%s: bad length %d", msg
, len(x
))
1007 for i
, b
:= range x
{
1009 t
.Errorf("%s: bad x[%d] = %x", msg
, i
, x
[i
])
1016 n
, err
= Sscanf("00010203 00010203", "%x %x", &a
, &b
)
1017 if n
!= 2 || err
!= nil {
1018 t
.Errorf("simple pair: got count, err = %d, %v; expected 2, nil", n
, err
)
1020 check("simple pair a", a
)
1021 check("simple pair b", b
)
1025 n
, err
= Sscanf("00010203:", "%x", &a
)
1026 if n
!= 1 || err
!= nil {
1027 t
.Errorf("colon: got count, err = %d, %v; expected 1, nil", n
, err
)
1032 n
, err
= Sscanf("00010203:00010203", "%x:%x", &a
, &b
)
1033 if n
!= 2 || err
!= nil {
1034 t
.Errorf("colon pair: got count, err = %d, %v; expected 2, nil", n
, err
)
1036 check("colon pair a", a
)
1037 check("colon pair b", b
)
1041 // This one fails because there is a hex byte after the data,
1042 // that is, an odd number of hex input bytes.
1043 n
, err
= Sscanf("000102034:", "%x", &a
)
1044 if n
!= 0 || err
== nil {
1045 t
.Errorf("odd count: got count, err = %d, %v; expected 0, error", n
, err
)
1049 func TestScanNewlinesAreSpaces(t
*testing
.T
) {
1051 var tests
= []struct {
1056 {"newlines", "1\n2\n", 2},
1057 {"no final newline", "1\n2", 2},
1058 {"newlines with spaces ", "1 \n 2 \n", 2},
1059 {"no final newline with spaces", "1 \n 2", 2},
1061 for _
, test
:= range tests
{
1062 n
, err
:= Sscan(test
.text
, &a
, &b
)
1063 if n
!= test
.count
{
1064 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1067 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1072 func TestScanlnNewlinesTerminate(t
*testing
.T
) {
1074 var tests
= []struct {
1080 {"one line one item", "1\n", 1, false},
1081 {"one line two items with spaces ", " 1 2 \n", 2, true},
1082 {"one line two items no newline", " 1 2", 2, true},
1083 {"two lines two items", "1\n2\n", 1, false},
1085 for _
, test
:= range tests
{
1086 n
, err
:= Sscanln(test
.text
, &a
, &b
)
1087 if n
!= test
.count
{
1088 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1090 if test
.ok
&& err
!= nil {
1091 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1093 if !test
.ok
&& err
== nil {
1094 t
.Errorf("%s: expected error; got none", test
.name
)
1099 func TestScanfNewlineMatchFormat(t
*testing
.T
) {
1101 var tests
= []struct {
1108 {"newline in both", "1\n2", "%d\n%d\n", 2, true},
1109 {"newline in input", "1\n2", "%d %d", 1, false},
1110 {"space-newline in input", "1 \n2", "%d %d", 1, false},
1111 {"newline in format", "1 2", "%d\n%d", 1, false},
1112 {"space-newline in format", "1 2", "%d \n%d", 1, false},
1113 {"space-newline in both", "1 \n2", "%d \n%d", 2, true},
1114 {"extra space in format", "1\n2", "%d\n %d", 2, true},
1115 {"two extra spaces in format", "1\n2", "%d \n %d", 2, true},
1117 for _
, test
:= range tests
{
1118 n
, err
:= Sscanf(test
.text
, test
.format
, &a
, &b
)
1119 if n
!= test
.count
{
1120 t
.Errorf("%s: expected to scan %d item(s), scanned %d", test
.name
, test
.count
, n
)
1122 if test
.ok
&& err
!= nil {
1123 t
.Errorf("%s: unexpected error: %s", test
.name
, err
)
1125 if !test
.ok
&& err
== nil {
1126 t
.Errorf("%s: expected error; got none", test
.name
)
1131 // Test for issue 12090: Was unreading at EOF, double-scanning a byte.
1133 type hexBytes
[2]byte
1135 func (h
*hexBytes
) Scan(ss ScanState
, verb rune
) error
{
1137 _
, err
:= Fscanf(ss
, "%4x", &b
)
1139 panic(err
) // Really shouldn't happen.
1145 func TestHexByte(t
*testing
.T
) {
1147 n
, err
:= Sscanln("0123\n", &h
)
1152 t
.Fatalf("expected 1 item; scanned %d", n
)
1154 if h
[0] != 0x01 || h
[1] != 0x23 {
1155 t
.Fatalf("expected 0123 got %x", h
)